<commit_before>#include <uri.hpp>
#include <iostream>

using namespace uri;

///////////////////////////////////////////////////////////////////////////////
const URI::Span_t URI::zero_span_;

///////////////////////////////////////////////////////////////////////////////
URI::URI(const std::string&& data) :
  uri_str_ {std::forward<const std::string>(data)}
{
  init_spans();
}

///////////////////////////////////////////////////////////////////////////////
URI::URI(const char* data) :
  uri_str_ {data}
{
  init_spans();
}

///////////////////////////////////////////////////////////////////////////////
std::string URI::path() const {
  return uri_str_.substr(path_.begin, path_.end);
}

///////////////////////////////////////////////////////////////////////////////
std::string URI::to_string() const{
  return uri_str_;
}

///////////////////////////////////////////////////////////////////////////////
void URI::parse(const std::string& uri) {
  static const std::regex uri_pattern_matcher
  {
    "^([\\w]+)?(\\://)?"        //< scheme
    "(([^:@]+)(\\:([^@]+))?@)?" //< username && password
    "([^/:?#]+)?(\\:(\\d+))?"   //< hostname && port
    "([^?#]+)"                  //< path
    "(\\?([^#]*))?"             //< query
    "(#(.*))?$"                 //< fragment
  };

  std::smatch uri_parts;

  if (std::regex_match(uri, uri_parts, uri_pattern_matcher)) {
    path_     = Span_t(uri_parts.position(10), uri_parts.length(10));

    userinfo_ = uri_parts.length(3)  ? Span_t(uri_parts.position(3),  uri_parts.length(3))  : zero_span_;
    host_     = uri_parts.length(7)  ? Span_t(uri_parts.position(7),  uri_parts.length(7))  : zero_span_;
    port_str_ = uri_parts.length(9)  ? Span_t(uri_parts.position(9),  uri_parts.length(9))  : zero_span_;
    query_    = uri_parts.length(11) ? Span_t(uri_parts.position(11), uri_parts.length(11)) : zero_span_;
    fragment_ = uri_parts.length(12) ? Span_t(uri_parts.position(12), uri_parts.length(12)) : zero_span_;
  }
}

///////////////////////////////////////////////////////////////////////////////
std::ostream& uri::operator<< (std::ostream& out, const URI& uri) {
  return out << uri.to_string();
}
<commit_msg>Changed implementation of URI constructors<commit_after>#include <uri.hpp>
#include <iostream>

using namespace uri;

///////////////////////////////////////////////////////////////////////////////
const URI::Span_t URI::zero_span_;

///////////////////////////////////////////////////////////////////////////////
URI::URI(const char* uri)
  : URI{std::string{uri}}
{}

///////////////////////////////////////////////////////////////////////////////
URI::URI(const std::string& uri)
  : uri_str_{uri}
  , port_{}
{
  parse(uri_str_);
  port_ = port_str_.begin ? static_cast<uint16_t>(std::stoi(port_str())) : 0;
}

///////////////////////////////////////////////////////////////////////////////
std::string URI::path() const {
  return uri_str_.substr(path_.begin, path_.end);
}

///////////////////////////////////////////////////////////////////////////////
std::string URI::to_string() const{
  return uri_str_;
}

///////////////////////////////////////////////////////////////////////////////
void URI::parse(const std::string& uri) {
  static const std::regex uri_pattern_matcher
  {
    "^([\\w]+)?(\\://)?"        //< scheme
    "(([^:@]+)(\\:([^@]+))?@)?" //< username && password
    "([^/:?#]+)?(\\:(\\d+))?"   //< hostname && port
    "([^?#]+)"                  //< path
    "(\\?([^#]*))?"             //< query
    "(#(.*))?$"                 //< fragment
  };

  std::smatch uri_parts;

  if (std::regex_match(uri, uri_parts, uri_pattern_matcher)) {
    path_     = Span_t(uri_parts.position(10), uri_parts.length(10));

    userinfo_ = uri_parts.length(3)  ? Span_t(uri_parts.position(3),  uri_parts.length(3))  : zero_span_;
    host_     = uri_parts.length(7)  ? Span_t(uri_parts.position(7),  uri_parts.length(7))  : zero_span_;
    port_str_ = uri_parts.length(9)  ? Span_t(uri_parts.position(9),  uri_parts.length(9))  : zero_span_;
    query_    = uri_parts.length(11) ? Span_t(uri_parts.position(11), uri_parts.length(11)) : zero_span_;
    fragment_ = uri_parts.length(12) ? Span_t(uri_parts.position(12), uri_parts.length(12)) : zero_span_;
  }
}

///////////////////////////////////////////////////////////////////////////////
std::ostream& uri::operator<< (std::ostream& out, const URI& uri) {
  return out << uri.to_string();
}
<|endoftext|>


<commit_before>// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util.h"

#ifdef _WIN32
#include <windows.h>
#include <io.h>
#endif

#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _WIN32
#include <sys/time.h>
#endif

#include <vector>

#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/sysctl.h>
#elif defined(__SVR4) && defined(__sun)
#include <unistd.h>
#include <sys/loadavg.h>
#elif defined(linux)
#include <sys/sysinfo.h>
#endif

#include "edit_distance.h"
#include "metrics.h"

void Fatal(const char* msg, ...) {
  va_list ap;
  fprintf(stderr, "ninja: fatal: ");
  va_start(ap, msg);
  vfprintf(stderr, msg, ap);
  va_end(ap);
  fprintf(stderr, "\n");
#ifdef _WIN32
  // On Windows, some tools may inject extra threads.
  // exit() may block on locks held by those threads, so forcibly exit.
  fflush(stderr);
  fflush(stdout);
  ExitProcess(1);
#else
  exit(1);
#endif
}

void Warning(const char* msg, ...) {
  va_list ap;
  fprintf(stderr, "ninja: warning: ");
  va_start(ap, msg);
  vfprintf(stderr, msg, ap);
  va_end(ap);
  fprintf(stderr, "\n");
}

void Error(const char* msg, ...) {
  va_list ap;
  fprintf(stderr, "ninja: error: ");
  va_start(ap, msg);
  vfprintf(stderr, msg, ap);
  va_end(ap);
  fprintf(stderr, "\n");
}

bool CanonicalizePath(string* path, string* err) {
  METRIC_RECORD("canonicalize str");
  size_t len = path->size();
  char* str = 0;
  if (len > 0)
    str = &(*path)[0];
  if (!CanonicalizePath(str, &len, err))
    return false;
  path->resize(len);
  return true;
}

bool CanonicalizePath(char* path, size_t* len, string* err) {
  // WARNING: this function is performance-critical; please benchmark
  // any changes you make to it.
  METRIC_RECORD("canonicalize path");
  if (*len == 0) {
    *err = "empty path";
    return false;
  }

  const int kMaxPathComponents = 30;
  char* components[kMaxPathComponents];
  int component_count = 0;

  char* start = path;
  char* dst = start;
  const char* src = start;
  const char* end = start + *len;

  if (*src == '/') {
#ifdef _WIN32
    // network path starts with //
    if (*len > 1 && *(src + 1) == '/') {
      src += 2;
      dst += 2;
    } else {
      ++src;
      ++dst;
    }
#else
    ++src;
    ++dst;
#endif
  }

  while (src < end) {
    if (*src == '.') {
      if (src + 1 == end || src[1] == '/') {
        // '.' component; eliminate.
        src += 2;
        continue;
      } else if (src[1] == '.' && (src + 2 == end || src[2] == '/')) {
        // '..' component.  Back up if possible.
        if (component_count > 0) {
          dst = components[component_count - 1];
          src += 3;
          --component_count;
        } else {
          *dst++ = *src++;
          *dst++ = *src++;
          *dst++ = *src++;
        }
        continue;
      }
    }

    if (*src == '/') {
      src++;
      continue;
    }

    if (component_count == kMaxPathComponents)
      Fatal("path has too many components");
    components[component_count] = dst;
    ++component_count;

    while (*src != '/' && src != end)
      *dst++ = *src++;
    *dst++ = *src++;  // Copy '/' or final \0 character as well.
  }

  if (dst == start) {
    *err = "path canonicalizes to the empty path";
    return false;
  }

  *len = dst - start - 1;
  return true;
}

int ReadFile(const string& path, string* contents, string* err) {
  FILE* f = fopen(path.c_str(), "r");
  if (!f) {
    err->assign(strerror(errno));
    return -errno;
  }

  char buf[64 << 10];
  size_t len;
  while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
    contents->append(buf, len);
  }
  if (ferror(f)) {
    err->assign(strerror(errno));  // XXX errno?
    contents->clear();
    fclose(f);
    return -errno;
  }
  fclose(f);
  return 0;
}

void SetCloseOnExec(int fd) {
#ifndef _WIN32
  int flags = fcntl(fd, F_GETFD);
  if (flags < 0) {
    perror("fcntl(F_GETFD)");
  } else {
    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
      perror("fcntl(F_SETFD)");
  }
#else
  HANDLE hd = (HANDLE) _get_osfhandle(fd);
  if (! SetHandleInformation(hd, HANDLE_FLAG_INHERIT, 0)) {
    fprintf(stderr, "SetHandleInformation(): %s", GetLastErrorString().c_str());
  }
#endif  // ! _WIN32
}

const char* SpellcheckStringV(const string& text,
                              const vector<const char*>& words) {
  const bool kAllowReplacements = true;
  const int kMaxValidEditDistance = 3;

  int min_distance = kMaxValidEditDistance + 1;
  const char* result = NULL;
  for (vector<const char*>::const_iterator i = words.begin();
       i != words.end(); ++i) {
    int distance = EditDistance(*i, text, kAllowReplacements,
                                kMaxValidEditDistance);
    if (distance < min_distance) {
      min_distance = distance;
      result = *i;
    }
  }
  return result;
}

const char* SpellcheckString(const string& text, ...) {
  va_list ap;
  va_start(ap, text);
  vector<const char*> words;
  const char* word;
  while ((word = va_arg(ap, const char*)))
    words.push_back(word);
  return SpellcheckStringV(text, words);
}

#ifdef _WIN32
string GetLastErrorString() {
  DWORD err = GetLastError();

  char* msg_buf;
  FormatMessageA(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (char*)&msg_buf,
        0,
        NULL);
  string msg = msg_buf;
  LocalFree(msg_buf);
  return msg;
}

void Win32Fatal(const char* function) {
  Fatal("%s: %s", function, GetLastErrorString().c_str());
}
#endif

static bool islatinalpha(int c) {
  // isalpha() is locale-dependent.
  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}

string StripAnsiEscapeCodes(const string& in) {
  string stripped;
  stripped.reserve(in.size());

  for (size_t i = 0; i < in.size(); ++i) {
    if (in[i] != '\33') {
      // Not an escape code.
      stripped.push_back(in[i]);
      continue;
    }

    // Only strip CSIs for now.
    if (i + 1 >= in.size()) break;
    if (in[i + 1] != '[') continue;  // Not a CSI.
    i += 2;

    // Skip everything up to and including the next [a-zA-Z].
    while (i < in.size() && !islatinalpha(in[i]))
      ++i;
  }
  return stripped;
}

#if defined(linux)
int GetProcessorCount() {
  return get_nprocs();
}
#elif defined(__APPLE__) || defined(__FreeBSD__)
int GetProcessorCount() {
  int processors;
  size_t processors_size = sizeof(processors);
  int name[] = {CTL_HW, HW_NCPU};
  if (sysctl(name, sizeof(name) / sizeof(int),
             &processors, &processors_size,
             NULL, 0) < 0) {
    return 0;
  }
  return processors;
}
#elif defined(_WIN32)
int GetProcessorCount() {
  SYSTEM_INFO info;
  GetSystemInfo(&info);
  return info.dwNumberOfProcessors;
}
#else
// This is what get_nprocs() should be doing in the Linux implementation
// above, but in a more standard way.
int GetProcessorCount() {
  return sysconf(_SC_NPROCESSORS_ONLN);
}
#endif

#ifdef _WIN32
double GetLoadAverage() {
  // TODO(nicolas.despres@gmail.com): Find a way to implement it on Windows.
  // Remember to also update Usage() when this is fixed.
  return -0.0f;
}
#else
double GetLoadAverage() {
  double loadavg[3] = { 0.0f, 0.0f, 0.0f };
  if (getloadavg(loadavg, 3) < 0) {
    // Maybe we should return an error here or the availability of
    // getloadavg(3) should be checked when ninja is configured.
    return -0.0f;
  }
  return loadavg[0];
}
#endif // _WIN32

string ElideMiddle(const string& str, size_t width) {
  const int kMargin = 3;  // Space for "...".
  string result = str;
  if (result.size() + kMargin > width) {
    size_t elide_size = (width - kMargin) / 2;
    result = result.substr(0, elide_size)
      + "..."
      + result.substr(result.size() - elide_size, elide_size);
  }
  return result;
}
<commit_msg>Improved error message with more information<commit_after>// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util.h"

#ifdef _WIN32
#include <windows.h>
#include <io.h>
#endif

#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef _WIN32
#include <sys/time.h>
#endif

#include <vector>

#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/sysctl.h>
#elif defined(__SVR4) && defined(__sun)
#include <unistd.h>
#include <sys/loadavg.h>
#elif defined(linux)
#include <sys/sysinfo.h>
#endif

#include "edit_distance.h"
#include "metrics.h"

void Fatal(const char* msg, ...) {
  va_list ap;
  fprintf(stderr, "ninja: fatal: ");
  va_start(ap, msg);
  vfprintf(stderr, msg, ap);
  va_end(ap);
  fprintf(stderr, "\n");
#ifdef _WIN32
  // On Windows, some tools may inject extra threads.
  // exit() may block on locks held by those threads, so forcibly exit.
  fflush(stderr);
  fflush(stdout);
  ExitProcess(1);
#else
  exit(1);
#endif
}

void Warning(const char* msg, ...) {
  va_list ap;
  fprintf(stderr, "ninja: warning: ");
  va_start(ap, msg);
  vfprintf(stderr, msg, ap);
  va_end(ap);
  fprintf(stderr, "\n");
}

void Error(const char* msg, ...) {
  va_list ap;
  fprintf(stderr, "ninja: error: ");
  va_start(ap, msg);
  vfprintf(stderr, msg, ap);
  va_end(ap);
  fprintf(stderr, "\n");
}

bool CanonicalizePath(string* path, string* err) {
  METRIC_RECORD("canonicalize str");
  size_t len = path->size();
  char* str = 0;
  if (len > 0)
    str = &(*path)[0];
  if (!CanonicalizePath(str, &len, err))
    return false;
  path->resize(len);
  return true;
}

bool CanonicalizePath(char* path, size_t* len, string* err) {
  // WARNING: this function is performance-critical; please benchmark
  // any changes you make to it.
  METRIC_RECORD("canonicalize path");
  if (*len == 0) {
    *err = "empty path";
    return false;
  }

  const int kMaxPathComponents = 30;
  char* components[kMaxPathComponents];
  int component_count = 0;

  char* start = path;
  char* dst = start;
  const char* src = start;
  const char* end = start + *len;

  if (*src == '/') {
#ifdef _WIN32
    // network path starts with //
    if (*len > 1 && *(src + 1) == '/') {
      src += 2;
      dst += 2;
    } else {
      ++src;
      ++dst;
    }
#else
    ++src;
    ++dst;
#endif
  }

  while (src < end) {
    if (*src == '.') {
      if (src + 1 == end || src[1] == '/') {
        // '.' component; eliminate.
        src += 2;
        continue;
      } else if (src[1] == '.' && (src + 2 == end || src[2] == '/')) {
        // '..' component.  Back up if possible.
        if (component_count > 0) {
          dst = components[component_count - 1];
          src += 3;
          --component_count;
        } else {
          *dst++ = *src++;
          *dst++ = *src++;
          *dst++ = *src++;
        }
        continue;
      }
    }

    if (*src == '/') {
      src++;
      continue;
    }

    if (component_count == kMaxPathComponents)
      Fatal("path has too many components : %s", path);
    components[component_count] = dst;
    ++component_count;

    while (*src != '/' && src != end)
      *dst++ = *src++;
    *dst++ = *src++;  // Copy '/' or final \0 character as well.
  }

  if (dst == start) {
    *err = "path canonicalizes to the empty path";
    return false;
  }

  *len = dst - start - 1;
  return true;
}

int ReadFile(const string& path, string* contents, string* err) {
  FILE* f = fopen(path.c_str(), "r");
  if (!f) {
    err->assign(strerror(errno));
    return -errno;
  }

  char buf[64 << 10];
  size_t len;
  while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
    contents->append(buf, len);
  }
  if (ferror(f)) {
    err->assign(strerror(errno));  // XXX errno?
    contents->clear();
    fclose(f);
    return -errno;
  }
  fclose(f);
  return 0;
}

void SetCloseOnExec(int fd) {
#ifndef _WIN32
  int flags = fcntl(fd, F_GETFD);
  if (flags < 0) {
    perror("fcntl(F_GETFD)");
  } else {
    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
      perror("fcntl(F_SETFD)");
  }
#else
  HANDLE hd = (HANDLE) _get_osfhandle(fd);
  if (! SetHandleInformation(hd, HANDLE_FLAG_INHERIT, 0)) {
    fprintf(stderr, "SetHandleInformation(): %s", GetLastErrorString().c_str());
  }
#endif  // ! _WIN32
}

const char* SpellcheckStringV(const string& text,
                              const vector<const char*>& words) {
  const bool kAllowReplacements = true;
  const int kMaxValidEditDistance = 3;

  int min_distance = kMaxValidEditDistance + 1;
  const char* result = NULL;
  for (vector<const char*>::const_iterator i = words.begin();
       i != words.end(); ++i) {
    int distance = EditDistance(*i, text, kAllowReplacements,
                                kMaxValidEditDistance);
    if (distance < min_distance) {
      min_distance = distance;
      result = *i;
    }
  }
  return result;
}

const char* SpellcheckString(const string& text, ...) {
  va_list ap;
  va_start(ap, text);
  vector<const char*> words;
  const char* word;
  while ((word = va_arg(ap, const char*)))
    words.push_back(word);
  return SpellcheckStringV(text, words);
}

#ifdef _WIN32
string GetLastErrorString() {
  DWORD err = GetLastError();

  char* msg_buf;
  FormatMessageA(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (char*)&msg_buf,
        0,
        NULL);
  string msg = msg_buf;
  LocalFree(msg_buf);
  return msg;
}

void Win32Fatal(const char* function) {
  Fatal("%s: %s", function, GetLastErrorString().c_str());
}
#endif

static bool islatinalpha(int c) {
  // isalpha() is locale-dependent.
  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}

string StripAnsiEscapeCodes(const string& in) {
  string stripped;
  stripped.reserve(in.size());

  for (size_t i = 0; i < in.size(); ++i) {
    if (in[i] != '\33') {
      // Not an escape code.
      stripped.push_back(in[i]);
      continue;
    }

    // Only strip CSIs for now.
    if (i + 1 >= in.size()) break;
    if (in[i + 1] != '[') continue;  // Not a CSI.
    i += 2;

    // Skip everything up to and including the next [a-zA-Z].
    while (i < in.size() && !islatinalpha(in[i]))
      ++i;
  }
  return stripped;
}

#if defined(linux)
int GetProcessorCount() {
  return get_nprocs();
}
#elif defined(__APPLE__) || defined(__FreeBSD__)
int GetProcessorCount() {
  int processors;
  size_t processors_size = sizeof(processors);
  int name[] = {CTL_HW, HW_NCPU};
  if (sysctl(name, sizeof(name) / sizeof(int),
             &processors, &processors_size,
             NULL, 0) < 0) {
    return 0;
  }
  return processors;
}
#elif defined(_WIN32)
int GetProcessorCount() {
  SYSTEM_INFO info;
  GetSystemInfo(&info);
  return info.dwNumberOfProcessors;
}
#else
// This is what get_nprocs() should be doing in the Linux implementation
// above, but in a more standard way.
int GetProcessorCount() {
  return sysconf(_SC_NPROCESSORS_ONLN);
}
#endif

#ifdef _WIN32
double GetLoadAverage() {
  // TODO(nicolas.despres@gmail.com): Find a way to implement it on Windows.
  // Remember to also update Usage() when this is fixed.
  return -0.0f;
}
#else
double GetLoadAverage() {
  double loadavg[3] = { 0.0f, 0.0f, 0.0f };
  if (getloadavg(loadavg, 3) < 0) {
    // Maybe we should return an error here or the availability of
    // getloadavg(3) should be checked when ninja is configured.
    return -0.0f;
  }
  return loadavg[0];
}
#endif // _WIN32

string ElideMiddle(const string& str, size_t width) {
  const int kMargin = 3;  // Space for "...".
  string result = str;
  if (result.size() + kMargin > width) {
    size_t elide_size = (width - kMargin) / 2;
    result = result.substr(0, elide_size)
      + "..."
      + result.substr(result.size() - elide_size, elide_size);
  }
  return result;
}
<|endoftext|>


<commit_before>#include "FileSystem.h"
#include "Log.h"

#ifndef PLATFORM_WINDOWS
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <alloca.h>

FD FS_Open(const char* filename, int flags)
{
	int		mode;
	int		oflags;
	int		ret;

	mode = S_IRUSR | S_IWUSR;
	oflags = 0;
	if ((flags & FS_CREATE) == FS_CREATE)
		oflags |= O_CREAT;
	if ((flags & FS_READWRITE) == FS_READWRITE)
		oflags |= O_RDWR;

	ret = open(filename, oflags, mode);
	if (ret < 0)
	{
		Log_Errno();
		return INVALID_FD;
	}
	return ret;
}

void FS_FileClose(FD fd)
{
	int	ret;

	ret = close(fd);
	if (ret < 0)
		Log_Errno();
}

int64_t FS_FileSeek(FD fd, uint64_t offset, int whence_)
{
	off_t	ret;
	int		whence;

	whence = -1;
	switch (whence_)
	{
	case FS_SEEK_SET:
		whence = SEEK_SET;
		break;
	case FS_SEEK_CUR:
		whence = SEEK_CUR;
		break;
	case FS_SEEK_END:
		whence = SEEK_END;
		break;
	default:
		return -1;
	}

	ret = lseek(fd, offset, whence);
	if (ret < 0)
		Log_Errno();
	return ret;
}

int FS_FileTruncate(FD fd, uint64_t length)
{
	int	ret;

	ret = ftruncate(fd, length);
	if (ret < 0)
		Log_Errno();
	return ret;
}

int64_t FS_FileSize(FD fd)
{
	int64_t		ret;
	struct stat	buf;

	ret = fstat(fd, &buf);
	if (ret < 0)
	{
		Log_Errno();
		return ret;
	}

	return buf.st_size;
}

ssize_t	FS_FileWrite(FD fd, const void* buf, size_t count)
{
	ssize_t	ret;

	ret = write(fd, buf, count);
	if (ret < 0)
		Log_Errno();
	return ret;
}

ssize_t	FS_FileWriteVector(FD fd, unsigned num, const void** buf, size_t *count)
{
	ssize_t			ret;
	struct iovec*	vecbuf;
	unsigned		i;

	vecbuf = (struct iovec*) alloca(sizeof(struct iovec) * num);
	for (i = 0; i < num; i++)
	{
		vecbuf[i].iov_base = (void*) buf[i];
		vecbuf[i].iov_len = count[i];
	}

	ret = writev(fd, vecbuf, num);
	if (ret < 0)
		Log_Errno();
	return ret;
}

ssize_t FS_FileRead(FD fd, void* buf, size_t count)
{
	ssize_t	ret;

	ret = read(fd, buf, count);
	if (ret < 0)
		Log_Errno();
	return ret;
}

ssize_t	FS_FileWriteOffs(FD fd, const void* buf, size_t count, uint64_t offset)
{
	ssize_t	ret;

	ret = pwrite(fd, buf, count, offset);
	if (ret < 0)
		Log_Errno();
	return ret;
}

ssize_t FS_FileReadOffs(FD fd, void* buf, size_t count, uint64_t offset)
{
	ssize_t	ret;

	ret = pread(fd, buf, count, offset);
	if (ret < 0)
		Log_Errno();
	return ret;
}

bool FS_Delete(const char* filename)
{
	int	ret;

	ret = unlink(filename);
	if (ret < 0)
	{
		Log_Errno();
		return false;
	}

	return true;
}

FS_Dir FS_OpenDir(const char* filename)
{
	DIR*	dir;

	dir = opendir(filename);
	if (dir == NULL)
	{
		Log_Errno();
		return NULL;
	}

	return (FS_Dir) dir;
}

FS_DirEntry	FS_ReadDir(FS_Dir dir)
{
	return (FS_DirEntry) readdir((DIR*) dir);
}

void FS_CloseDir(FS_Dir dir)
{
	int ret;

	ret = closedir((DIR*) dir);
	if (ret < 0)
		Log_Errno();
}

bool FS_CreateDir(const char* filename)
{
	int	ret;

	ret = mkdir(filename, S_IRUSR | S_IWUSR);
	if (ret < 0)
	{
		Log_Errno();
		return false;
	}
	return true;
}

bool FS_DeleteDir(const char* filename)
{
	int	ret;

	ret = rmdir(filename);
	if (ret < 0)
	{
		Log_Errno();
		return false;
	}
	return true;
}

const char*	FS_DirEntryName(FS_DirEntry dirent)
{
	return ((struct dirent*) dirent)->d_name;
}

bool FS_IsDirectory(const char* path)
{
	struct stat s;
	if (stat(path, &s) != 0)
		return false;
	if (s.st_mode & S_IFDIR)
		return true;
	return false;
}

int64_t	FS_FreeDiskSpace(const char* path)
{
	struct statvfs sv;

	if (statvfs(path, &sv) < 0)
		return -1;

	return ((int64_t) sv.f_bavail * sv.f_frsize);
}

void FS_Sync()
{
	sync();
}

#else

// TODO: Windows port

int64_t	FS_FreeDiskSpace(const char* path)
{
	ULARGE_INTEGER	bytes;

	if (!GetDiskFreeSpaceEx(path, &bytes, NULL, NULL))
		return -1;
	return bytes.QuadPart;
}

#endif
<commit_msg>Changed alloca to standard stack allocation.<commit_after>#include "FileSystem.h"
#include "Log.h"

#ifndef PLATFORM_WINDOWS
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <alloca.h>

FD FS_Open(const char* filename, int flags)
{
	int		mode;
	int		oflags;
	int		ret;

	mode = S_IRUSR | S_IWUSR;
	oflags = 0;
	if ((flags & FS_CREATE) == FS_CREATE)
		oflags |= O_CREAT;
	if ((flags & FS_READWRITE) == FS_READWRITE)
		oflags |= O_RDWR;

	ret = open(filename, oflags, mode);
	if (ret < 0)
	{
		Log_Errno();
		return INVALID_FD;
	}
	return ret;
}

void FS_FileClose(FD fd)
{
	int	ret;

	ret = close(fd);
	if (ret < 0)
		Log_Errno();
}

int64_t FS_FileSeek(FD fd, uint64_t offset, int whence_)
{
	off_t	ret;
	int		whence;

	whence = -1;
	switch (whence_)
	{
	case FS_SEEK_SET:
		whence = SEEK_SET;
		break;
	case FS_SEEK_CUR:
		whence = SEEK_CUR;
		break;
	case FS_SEEK_END:
		whence = SEEK_END;
		break;
	default:
		return -1;
	}

	ret = lseek(fd, offset, whence);
	if (ret < 0)
		Log_Errno();
	return ret;
}

int FS_FileTruncate(FD fd, uint64_t length)
{
	int	ret;

	ret = ftruncate(fd, length);
	if (ret < 0)
		Log_Errno();
	return ret;
}

int64_t FS_FileSize(FD fd)
{
	int64_t		ret;
	struct stat	buf;

	ret = fstat(fd, &buf);
	if (ret < 0)
	{
		Log_Errno();
		return ret;
	}

	return buf.st_size;
}

ssize_t	FS_FileWrite(FD fd, const void* buf, size_t count)
{
	ssize_t	ret;

	ret = write(fd, buf, count);
	if (ret < 0)
		Log_Errno();
	return ret;
}

ssize_t	FS_FileWriteVector(FD fd, unsigned num, const void** buf, size_t *count)
{
	ssize_t			ret;
	struct iovec	vecbuf[num];
	unsigned		i;

	for (i = 0; i < num; i++)
	{
		vecbuf[i].iov_base = (void*) buf[i];
		vecbuf[i].iov_len = count[i];
	}

	ret = writev(fd, vecbuf, num);
	if (ret < 0)
		Log_Errno();
	return ret;
}

ssize_t FS_FileRead(FD fd, void* buf, size_t count)
{
	ssize_t	ret;

	ret = read(fd, buf, count);
	if (ret < 0)
		Log_Errno();
	return ret;
}

ssize_t	FS_FileWriteOffs(FD fd, const void* buf, size_t count, uint64_t offset)
{
	ssize_t	ret;

	ret = pwrite(fd, buf, count, offset);
	if (ret < 0)
		Log_Errno();
	return ret;
}

ssize_t FS_FileReadOffs(FD fd, void* buf, size_t count, uint64_t offset)
{
	ssize_t	ret;

	ret = pread(fd, buf, count, offset);
	if (ret < 0)
		Log_Errno();
	return ret;
}

bool FS_Delete(const char* filename)
{
	int	ret;

	ret = unlink(filename);
	if (ret < 0)
	{
		Log_Errno();
		return false;
	}

	return true;
}

FS_Dir FS_OpenDir(const char* filename)
{
	DIR*	dir;

	dir = opendir(filename);
	if (dir == NULL)
	{
		Log_Errno();
		return NULL;
	}

	return (FS_Dir) dir;
}

FS_DirEntry	FS_ReadDir(FS_Dir dir)
{
	return (FS_DirEntry) readdir((DIR*) dir);
}

void FS_CloseDir(FS_Dir dir)
{
	int ret;

	ret = closedir((DIR*) dir);
	if (ret < 0)
		Log_Errno();
}

bool FS_CreateDir(const char* filename)
{
	int	ret;

	ret = mkdir(filename, S_IRUSR | S_IWUSR);
	if (ret < 0)
	{
		Log_Errno();
		return false;
	}
	return true;
}

bool FS_DeleteDir(const char* filename)
{
	int	ret;

	ret = rmdir(filename);
	if (ret < 0)
	{
		Log_Errno();
		return false;
	}
	return true;
}

const char*	FS_DirEntryName(FS_DirEntry dirent)
{
	return ((struct dirent*) dirent)->d_name;
}

bool FS_IsDirectory(const char* path)
{
	struct stat s;
	if (stat(path, &s) != 0)
		return false;
	if (s.st_mode & S_IFDIR)
		return true;
	return false;
}

int64_t	FS_FreeDiskSpace(const char* path)
{
	struct statvfs sv;

	if (statvfs(path, &sv) < 0)
		return -1;

	return ((int64_t) sv.f_bavail * sv.f_frsize);
}

void FS_Sync()
{
	sync();
}

#else

// TODO: Windows port

int64_t	FS_FreeDiskSpace(const char* path)
{
	ULARGE_INTEGER	bytes;

	if (!GetDiskFreeSpaceEx(path, &bytes, NULL, NULL))
		return -1;
	return bytes.QuadPart;
}

#endif
<|endoftext|>


<commit_before>/*
 * System_stateLogin.cpp
 *
 *  Created on: Jun 19, 2014
 *      Author: Pimenta
 */

#include "System.hpp"

void System::stateLogin() {

}
<commit_msg>Login feito<commit_after>/*
 * System_stateLogin.cpp
 *
 *  Created on: Jun 19, 2014
 *      Author: Pimenta
 */

// this
#include "System.hpp"

// standard
#include <cstring>
#include <cstdio>
#include <string>

// local
#include "Defines.hpp"
#include "Concurrency.hpp"
#include "Network.hpp"
#include "Helpers.hpp"

using namespace std;
using namespace concurrency;
using namespace network;
using namespace helpers;

// FIXME: esse define eh zoado, tem que tirar
#define SIZE_HTTPSERVER_MAXBUF 0x1000

// static variables
static TCPConnection* client = nullptr;

void System::stateLogin() {
  client = httpTCPServer.accept();
  if (client == nullptr)
    return;

  vector<char> data = client->recv(SIZE_HTTPSERVER_MAXBUF);
  data.push_back(0);

  char fn[100], buftmp[100];
  sscanf(&data[0], "%s %s", buftmp, fn);

  if (fn[1] == '?') {
      if(loginAttempt(fn, users, localAddress.ip))
        state = STATE_IDLE;
    } else {
      if (string(fn) == "/")
        strcpy(fn, "/index.html");
      FILE* fp = fopen((string("./www") + fn).c_str(), "rb");
      if (fp) {
        if (string(fn).find(".html") != string::npos) {
          const char* header =
            "HTTP/1.1 200 OK\r\n"
            "Connection: close\r\r"
            "Content-Type: text/html\r\n"
            "\r\n"
          ;
          client->send(header, strlen(header));
        }
        else if (string(fn).find(".css") != string::npos) {
          const char* header =
            "HTTP/1.1 200 OK\r\n"
            "Connection: close\r\r"
            "Content-Type: text/css\r\n"
            "\r\n"
          ;
          client->send(header, strlen(header));
        }
        else if (string(fn).find(".js") != string::npos) {
          const char* header =
            "HTTP/1.1 200 OK\r\n"
            "Connection: close\r\r"
            "Content-Type: application/javascript\r\n"
            "\r\n"
          ;
          client->send(header, strlen(header));
        }
        else {
          const char* header =
            "HTTP/1.1 200 OK\r\n"
            "Connection: close\r\r"
            "Content-Type: application/octet-stream\r\n"
            "\r\n"
          ;
          client->send(header, strlen(header));
        }
        client->send(readFile(fp));
        fclose(fp);
      }
      else {
        const char* msg = "Pagina nao encontrada.";
        client->send(msg, strlen(msg) + 1);
      }
    }

    delete client;
    client = nullptr;
}

int loginAttempt(char* data, map<uint32_t, User>& users, uint32_t ip){
  string input = string(data).substr(2, strlen(data));
  for(auto& kv : System::users){
    if(string(kv.second.name) == input){
      client->send("0", 2);
      return 0;
    }
  }

  users[ip] = User(input);
  client->send("1", 2);
  return 1;
}
<|endoftext|>


<commit_before>// $Id$

/*
Copyright (c) 2007-2011, Trustees of The Leland Stanford Junior University
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the Stanford University nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <iostream>
#include <sstream>
#include "random_utils.hpp"
#include "traffic.hpp"

TrafficPattern::TrafficPattern(int nodes)
: _nodes(nodes)
{
  if(nodes <= 0) {
    cout << "Error: Traffic patterns require at least one node." << endl;
    exit(-1);
  }
}

TrafficPattern * TrafficPattern::New(string const & pattern, int nodes)
{
  string pattern_name;
  string param_str;
  size_t left = pattern.find_first_of('(');
  if(left == string::npos) {
    pattern_name = pattern;
    param_str = "{}";
  } else {
    pattern_name = pattern.substr(0, left);
    size_t right = pattern.find_last_of(')');
    if(right == string::npos) {
      param_str = pattern.substr(left+1);
    } else {
      param_str = pattern.substr(left+1, right-left-1);
    }
  }
  vector<string> params = tokenize('{' + param_str + '}');

  TrafficPattern * result = NULL;
  if(pattern_name == "bitcomp") {
    result = new BitCompTrafficPattern(nodes);
  } else if(pattern_name == "transpose") {
    result = new TransposeTrafficPattern(nodes);
  } else if(pattern_name == "bitrev") {
    result = new BitRevTrafficPattern(nodes);
  } else if(pattern_name == "shuffle") {
    result = new ShuffleTrafficPattern(nodes);
  } else if(pattern_name == "randperm") {
    int perm_seed = params.empty() ? 0 : atoi(params[0].c_str());
    result = new RandomPermutationTrafficPattern(nodes, perm_seed);
  } else if(pattern_name == "uniform") {
    result = new UniformRandomTrafficPattern(nodes);
  } else if(pattern_name == "background") {
    vector<string> excludes_str = tokenize(params[0]);
    vector<int> excludes(excludes_str.size());
    for(size_t i = 0; i < excludes.size(); ++i) {
      excludes[i] = atoi(excludes_str[i].c_str());
    }
    result = new UniformBackgroundTrafficPattern(nodes, excludes);
  } else if(pattern_name == "diagonal") {
    result = new DiagonalTrafficPattern(nodes);
  } else if(pattern_name == "asymmetric") {
    result = new AsymmetricTrafficPattern(nodes);
  } else if(pattern_name == "taper64") {
    result = new Taper64TrafficPattern(nodes);
  } else if((pattern_name == "tornado") || (pattern_name == "neighbor") ||
	    (pattern_name == "bad_dragon") || (pattern_name == "badperm_yarc")) {
    if(params.size() < 3) {
      cout << "Error: Missing parameters for digit permutation traffic pattern: " << pattern << endl;
      exit(-1);
    }
    int k = atoi(params[0].c_str());
    int n = atoi(params[1].c_str());
    int xr = atoi(params[2].c_str());
    if(pattern_name == "tornado") {
      result = new TornadoTrafficPattern(nodes, k, n, xr);
    } else if(pattern_name == "neighbor") {
      result = new NeighborTrafficPattern(nodes, k, n, xr);
    } else if(pattern_name == "bad_dragon") {
      result = new BadPermDFlyTrafficPattern(nodes, k, n, xr);
    } else if(pattern_name == "badperm_yarc") {
      result = new BadPermYarcTrafficPattern(nodes, k, n, xr);
    }
  } else if(pattern_name == "hotspot") {
    if(params.empty()) {
      cout << "Error: Missing parameter for hotspot traffic pattern: " << pattern << endl;
      exit(-1);
    }
    vector<string> hotspots_str = tokenize(params[0]);
    vector<int> hotspots(hotspots_str.size());
    for(size_t i = 0; i < hotspots.size(); ++i) {
      hotspots[i] = atoi(hotspots_str[i].c_str());
    }
    vector<int> rates(hotspots.size(), 1);
    if(params.size() >= 2) {
      vector<string> rates_str = tokenize(params[1]);
      rates_str.resize(hotspots.size(), rates_str.back());
      for(size_t i = 0; i < rates.size(); ++i) {
	rates[i] = atoi(rates_str[i].c_str());
      }
    }
    result = new HotSpotTrafficPattern(nodes, hotspots, rates);
  } else {
    cout << "Error: Unknown traffic pattern: " << pattern << endl;
    exit(-1);
  }
  return result;
}

TrafficPattern * TrafficPattern::New(string const & pattern, int nodes, Configuration const & config)
{
  TrafficPattern * result = NULL;
  if((pattern == "tornado") || (pattern == "neighbor") ||
     (pattern == "bad_dragon") || (pattern == "badperm_yarc")) {
    int k = config.GetInt("k");
    int n = config.GetInt("n");
    int xr = config.GetInt("xr");
    ostringstream ss;
    ss << pattern << '(' << k << ',' << n << ',' << xr << ')';
    result = New(ss.str(), nodes);
  } else {
    result = New(pattern, nodes);
  }
  return result;
}

PermutationTrafficPattern::PermutationTrafficPattern(int nodes)
  : TrafficPattern(nodes)
{

}

BitPermutationTrafficPattern::BitPermutationTrafficPattern(int nodes)
  : PermutationTrafficPattern(nodes)
{
  if((nodes & -nodes) != nodes) {
    cout << "Error: Bit permutation traffic patterns require the number of "
	 << "nodes to be a power of two." << endl;
    exit(-1);
  }
}

BitCompTrafficPattern::BitCompTrafficPattern(int nodes)
  : BitPermutationTrafficPattern(nodes)
{

}

int BitCompTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const mask = _nodes - 1;
  return ~source & mask;
}

TransposeTrafficPattern::TransposeTrafficPattern(int nodes)
  : BitPermutationTrafficPattern(nodes), _shift(0)
{
  while(nodes >>= 1) {
    ++_shift;
  }
  if(_shift % 2) {
    cout << "Error: Transpose traffic pattern requires the number of nodes to "
	 << "be an even power of two." << endl;
    exit(-1);
  }
  _shift/=2;
}

int TransposeTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const mask_lo = (1 << _shift) - 1;
  int const mask_hi = mask_lo << _shift;
  return (((source >> _shift) & mask_lo) | ((source << _shift) & mask_hi));
}

BitRevTrafficPattern::BitRevTrafficPattern(int nodes)
  : BitPermutationTrafficPattern(nodes)
{

}

int BitRevTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int result = 0;
  for(int n = _nodes; n > 1; n >>= 1) {
    result = (result << 1) | (source % 2);
    source >>= 1;
  }
  return result;
}

ShuffleTrafficPattern::ShuffleTrafficPattern(int nodes)
  : BitPermutationTrafficPattern(nodes)
{

}

int ShuffleTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const shifted = source << 1;
  return ((shifted & (_nodes - 1)) | bool(shifted & _nodes));
}

DigitPermutationTrafficPattern::DigitPermutationTrafficPattern(int nodes, int k,
							       int n, int xr)
  : PermutationTrafficPattern(nodes), _k(k), _n(n), _xr(xr)
{

}

TornadoTrafficPattern::TornadoTrafficPattern(int nodes, int k, int n, int xr)
  : DigitPermutationTrafficPattern(nodes, k, n, xr)
{

}

int TornadoTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int offset = 1;
  int result = 0;

  for(int n = 0; n < _n; ++n) {
    result += offset *
      (((source / offset) % (_xr * _k) + ((_xr * _k) / 2 - 1)) % (_xr * _k));
    offset *= (_xr * _k);
  }
  return result;
}

NeighborTrafficPattern::NeighborTrafficPattern(int nodes, int k, int n, int xr)
  : DigitPermutationTrafficPattern(nodes, k, n, xr)
{

}

int NeighborTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int offset = 1;
  int result = 0;

  for(int n = 0; n < _n; ++n) {
    result += offset *
      (((source / offset) % (_xr * _k) + 1) % (_xr * _k));
    offset *= (_xr * _k);
  }
  return result;
}

RandomPermutationTrafficPattern::RandomPermutationTrafficPattern(int nodes,
								 int seed)
  : TrafficPattern(nodes)
{
  _dest.resize(nodes);
  randomize(seed);
}

void RandomPermutationTrafficPattern::randomize(int seed)
{
  unsigned long prev_seed = RandomIntLong( );
  RandomSeed(seed);

  _dest.assign(_nodes, -1);

  for(int i = 0; i < _nodes; ++i) {
    int ind = RandomInt(_nodes - 1 - i);

    int j = 0;
    int cnt = 0;
    while((cnt < ind) || (_dest[j] != -1)) {
      if(_dest[j] == -1) {
	++cnt;
      }
      ++j;
      assert(j < _nodes);
    }

    _dest[j] = i;
  }

  RandomSeed(prev_seed);
}

int RandomPermutationTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  assert((_dest[source] >= 0) && (_dest[source] < _nodes));
  return _dest[source];
}

RandomTrafficPattern::RandomTrafficPattern(int nodes)
  : TrafficPattern(nodes)
{

}

UniformRandomTrafficPattern::UniformRandomTrafficPattern(int nodes)
  : RandomTrafficPattern(nodes)
{

}

int UniformRandomTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  return RandomInt(_nodes - 1);
}

UniformBackgroundTrafficPattern::UniformBackgroundTrafficPattern(int nodes, vector<int> excluded_nodes)
  : RandomTrafficPattern(nodes)
{
  for(size_t i = 0; i < excluded_nodes.size(); ++i) {
    int const node = excluded_nodes[i];
    assert((node >= 0) && (node < _nodes));
    _excluded.insert(node);
  }
}

int UniformBackgroundTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int result;

  do {
    result = RandomInt(_nodes - 1);
  } while(_excluded.count(result) > 0);

  return result;
}

DiagonalTrafficPattern::DiagonalTrafficPattern(int nodes)
  : RandomTrafficPattern(nodes)
{

}

int DiagonalTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  return ((RandomInt(2) == 0) ? ((source + 1) % _nodes) : source);
}

AsymmetricTrafficPattern::AsymmetricTrafficPattern(int nodes)
  : RandomTrafficPattern(nodes)
{

}

int AsymmetricTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const half = _nodes / 2;
  return (source % half) + (RandomInt(1) ? half : 0);
}

Taper64TrafficPattern::Taper64TrafficPattern(int nodes)
  : RandomTrafficPattern(nodes)
{
  if(nodes != 64) {
    cout << "Error: Tthe Taper64 traffic pattern requires the number of nodes "
	 << "to be exactly 64." << endl;
    exit(-1);
  }
}

int Taper64TrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  if(RandomInt(1)) {
    return ((64 + source + 8 * (RandomInt(2) - 1) + (RandomInt(2) - 1)) % 64);
  } else {
    return RandomInt(_nodes - 1);
  }
}

BadPermDFlyTrafficPattern::BadPermDFlyTrafficPattern(int nodes, int k, int n,
						     int xr)
  : DigitPermutationTrafficPattern(nodes, k, n, xr)
{

}

int BadPermDFlyTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int const grp_size_routers = 2 * (_xr * _k);
  int const grp_size_nodes = grp_size_routers * (_xr * _k);

  return ((RandomInt(grp_size_nodes - 1) + ((source / grp_size_nodes) + 1) * grp_size_nodes) % _nodes);
}

BadPermYarcTrafficPattern::BadPermYarcTrafficPattern(int nodes, int k, int n,
						     int xr)
  : DigitPermutationTrafficPattern(nodes, k, n, xr)
{

}

int BadPermYarcTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const row = source / (_xr * _k);
  return RandomInt((_xr * _k) - 1) * (_xr * _k) + row;
}

HotSpotTrafficPattern::HotSpotTrafficPattern(int nodes, vector<int> hotspots,
					     vector<int> rates)
  : TrafficPattern(nodes), _hotspots(hotspots), _rates(rates), _max_val(-1)
{
  assert(!_hotspots.empty());
  size_t const size = _hotspots.size();
  _rates.resize(size, _rates.empty() ? 1 : _rates.back());
  for(size_t i = 0; i < size; ++i) {
    int const hotspot = _hotspots[i];
    assert((hotspot >= 0) && (hotspot < _nodes));
    int const rate = _rates[i];
    assert(rate >= 0);
    _max_val += rate;
  }
}

int HotSpotTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int pct = RandomInt(_max_val);

  for(size_t i = 0; i < (_hotspots.size() - 1); ++i) {
    int const limit = _rates[i];
    if(limit > pct) {
      return _hotspots[i];
    } else {
      pct -= limit;
    }
  }
  assert(_rates.back() > pct);
  return _hotspots.back();
}
<commit_msg>replace divide-by-two with shift<commit_after>// $Id$

/*
Copyright (c) 2007-2011, Trustees of The Leland Stanford Junior University
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the Stanford University nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <iostream>
#include <sstream>
#include "random_utils.hpp"
#include "traffic.hpp"

TrafficPattern::TrafficPattern(int nodes)
: _nodes(nodes)
{
  if(nodes <= 0) {
    cout << "Error: Traffic patterns require at least one node." << endl;
    exit(-1);
  }
}

TrafficPattern * TrafficPattern::New(string const & pattern, int nodes)
{
  string pattern_name;
  string param_str;
  size_t left = pattern.find_first_of('(');
  if(left == string::npos) {
    pattern_name = pattern;
    param_str = "{}";
  } else {
    pattern_name = pattern.substr(0, left);
    size_t right = pattern.find_last_of(')');
    if(right == string::npos) {
      param_str = pattern.substr(left+1);
    } else {
      param_str = pattern.substr(left+1, right-left-1);
    }
  }
  vector<string> params = tokenize('{' + param_str + '}');

  TrafficPattern * result = NULL;
  if(pattern_name == "bitcomp") {
    result = new BitCompTrafficPattern(nodes);
  } else if(pattern_name == "transpose") {
    result = new TransposeTrafficPattern(nodes);
  } else if(pattern_name == "bitrev") {
    result = new BitRevTrafficPattern(nodes);
  } else if(pattern_name == "shuffle") {
    result = new ShuffleTrafficPattern(nodes);
  } else if(pattern_name == "randperm") {
    int perm_seed = params.empty() ? 0 : atoi(params[0].c_str());
    result = new RandomPermutationTrafficPattern(nodes, perm_seed);
  } else if(pattern_name == "uniform") {
    result = new UniformRandomTrafficPattern(nodes);
  } else if(pattern_name == "background") {
    vector<string> excludes_str = tokenize(params[0]);
    vector<int> excludes(excludes_str.size());
    for(size_t i = 0; i < excludes.size(); ++i) {
      excludes[i] = atoi(excludes_str[i].c_str());
    }
    result = new UniformBackgroundTrafficPattern(nodes, excludes);
  } else if(pattern_name == "diagonal") {
    result = new DiagonalTrafficPattern(nodes);
  } else if(pattern_name == "asymmetric") {
    result = new AsymmetricTrafficPattern(nodes);
  } else if(pattern_name == "taper64") {
    result = new Taper64TrafficPattern(nodes);
  } else if((pattern_name == "tornado") || (pattern_name == "neighbor") ||
	    (pattern_name == "bad_dragon") || (pattern_name == "badperm_yarc")) {
    if(params.size() < 3) {
      cout << "Error: Missing parameters for digit permutation traffic pattern: " << pattern << endl;
      exit(-1);
    }
    int k = atoi(params[0].c_str());
    int n = atoi(params[1].c_str());
    int xr = atoi(params[2].c_str());
    if(pattern_name == "tornado") {
      result = new TornadoTrafficPattern(nodes, k, n, xr);
    } else if(pattern_name == "neighbor") {
      result = new NeighborTrafficPattern(nodes, k, n, xr);
    } else if(pattern_name == "bad_dragon") {
      result = new BadPermDFlyTrafficPattern(nodes, k, n, xr);
    } else if(pattern_name == "badperm_yarc") {
      result = new BadPermYarcTrafficPattern(nodes, k, n, xr);
    }
  } else if(pattern_name == "hotspot") {
    if(params.empty()) {
      cout << "Error: Missing parameter for hotspot traffic pattern: " << pattern << endl;
      exit(-1);
    }
    vector<string> hotspots_str = tokenize(params[0]);
    vector<int> hotspots(hotspots_str.size());
    for(size_t i = 0; i < hotspots.size(); ++i) {
      hotspots[i] = atoi(hotspots_str[i].c_str());
    }
    vector<int> rates(hotspots.size(), 1);
    if(params.size() >= 2) {
      vector<string> rates_str = tokenize(params[1]);
      rates_str.resize(hotspots.size(), rates_str.back());
      for(size_t i = 0; i < rates.size(); ++i) {
	rates[i] = atoi(rates_str[i].c_str());
      }
    }
    result = new HotSpotTrafficPattern(nodes, hotspots, rates);
  } else {
    cout << "Error: Unknown traffic pattern: " << pattern << endl;
    exit(-1);
  }
  return result;
}

TrafficPattern * TrafficPattern::New(string const & pattern, int nodes, Configuration const & config)
{
  TrafficPattern * result = NULL;
  if((pattern == "tornado") || (pattern == "neighbor") ||
     (pattern == "bad_dragon") || (pattern == "badperm_yarc")) {
    int k = config.GetInt("k");
    int n = config.GetInt("n");
    int xr = config.GetInt("xr");
    ostringstream ss;
    ss << pattern << '(' << k << ',' << n << ',' << xr << ')';
    result = New(ss.str(), nodes);
  } else {
    result = New(pattern, nodes);
  }
  return result;
}

PermutationTrafficPattern::PermutationTrafficPattern(int nodes)
  : TrafficPattern(nodes)
{

}

BitPermutationTrafficPattern::BitPermutationTrafficPattern(int nodes)
  : PermutationTrafficPattern(nodes)
{
  if((nodes & -nodes) != nodes) {
    cout << "Error: Bit permutation traffic patterns require the number of "
	 << "nodes to be a power of two." << endl;
    exit(-1);
  }
}

BitCompTrafficPattern::BitCompTrafficPattern(int nodes)
  : BitPermutationTrafficPattern(nodes)
{

}

int BitCompTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const mask = _nodes - 1;
  return ~source & mask;
}

TransposeTrafficPattern::TransposeTrafficPattern(int nodes)
  : BitPermutationTrafficPattern(nodes), _shift(0)
{
  while(nodes >>= 1) {
    ++_shift;
  }
  if(_shift % 2) {
    cout << "Error: Transpose traffic pattern requires the number of nodes to "
	 << "be an even power of two." << endl;
    exit(-1);
  }
  _shift >>= 2;
}

int TransposeTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const mask_lo = (1 << _shift) - 1;
  int const mask_hi = mask_lo << _shift;
  return (((source >> _shift) & mask_lo) | ((source << _shift) & mask_hi));
}

BitRevTrafficPattern::BitRevTrafficPattern(int nodes)
  : BitPermutationTrafficPattern(nodes)
{

}

int BitRevTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int result = 0;
  for(int n = _nodes; n > 1; n >>= 1) {
    result = (result << 1) | (source % 2);
    source >>= 1;
  }
  return result;
}

ShuffleTrafficPattern::ShuffleTrafficPattern(int nodes)
  : BitPermutationTrafficPattern(nodes)
{

}

int ShuffleTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const shifted = source << 1;
  return ((shifted & (_nodes - 1)) | bool(shifted & _nodes));
}

DigitPermutationTrafficPattern::DigitPermutationTrafficPattern(int nodes, int k,
							       int n, int xr)
  : PermutationTrafficPattern(nodes), _k(k), _n(n), _xr(xr)
{

}

TornadoTrafficPattern::TornadoTrafficPattern(int nodes, int k, int n, int xr)
  : DigitPermutationTrafficPattern(nodes, k, n, xr)
{

}

int TornadoTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int offset = 1;
  int result = 0;

  for(int n = 0; n < _n; ++n) {
    result += offset *
      (((source / offset) % (_xr * _k) + ((_xr * _k) / 2 - 1)) % (_xr * _k));
    offset *= (_xr * _k);
  }
  return result;
}

NeighborTrafficPattern::NeighborTrafficPattern(int nodes, int k, int n, int xr)
  : DigitPermutationTrafficPattern(nodes, k, n, xr)
{

}

int NeighborTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int offset = 1;
  int result = 0;

  for(int n = 0; n < _n; ++n) {
    result += offset *
      (((source / offset) % (_xr * _k) + 1) % (_xr * _k));
    offset *= (_xr * _k);
  }
  return result;
}

RandomPermutationTrafficPattern::RandomPermutationTrafficPattern(int nodes,
								 int seed)
  : TrafficPattern(nodes)
{
  _dest.resize(nodes);
  randomize(seed);
}

void RandomPermutationTrafficPattern::randomize(int seed)
{
  unsigned long prev_seed = RandomIntLong( );
  RandomSeed(seed);

  _dest.assign(_nodes, -1);

  for(int i = 0; i < _nodes; ++i) {
    int ind = RandomInt(_nodes - 1 - i);

    int j = 0;
    int cnt = 0;
    while((cnt < ind) || (_dest[j] != -1)) {
      if(_dest[j] == -1) {
	++cnt;
      }
      ++j;
      assert(j < _nodes);
    }

    _dest[j] = i;
  }

  RandomSeed(prev_seed);
}

int RandomPermutationTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  assert((_dest[source] >= 0) && (_dest[source] < _nodes));
  return _dest[source];
}

RandomTrafficPattern::RandomTrafficPattern(int nodes)
  : TrafficPattern(nodes)
{

}

UniformRandomTrafficPattern::UniformRandomTrafficPattern(int nodes)
  : RandomTrafficPattern(nodes)
{

}

int UniformRandomTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  return RandomInt(_nodes - 1);
}

UniformBackgroundTrafficPattern::UniformBackgroundTrafficPattern(int nodes, vector<int> excluded_nodes)
  : RandomTrafficPattern(nodes)
{
  for(size_t i = 0; i < excluded_nodes.size(); ++i) {
    int const node = excluded_nodes[i];
    assert((node >= 0) && (node < _nodes));
    _excluded.insert(node);
  }
}

int UniformBackgroundTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int result;

  do {
    result = RandomInt(_nodes - 1);
  } while(_excluded.count(result) > 0);

  return result;
}

DiagonalTrafficPattern::DiagonalTrafficPattern(int nodes)
  : RandomTrafficPattern(nodes)
{

}

int DiagonalTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  return ((RandomInt(2) == 0) ? ((source + 1) % _nodes) : source);
}

AsymmetricTrafficPattern::AsymmetricTrafficPattern(int nodes)
  : RandomTrafficPattern(nodes)
{

}

int AsymmetricTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const half = _nodes / 2;
  return (source % half) + (RandomInt(1) ? half : 0);
}

Taper64TrafficPattern::Taper64TrafficPattern(int nodes)
  : RandomTrafficPattern(nodes)
{
  if(nodes != 64) {
    cout << "Error: Tthe Taper64 traffic pattern requires the number of nodes "
	 << "to be exactly 64." << endl;
    exit(-1);
  }
}

int Taper64TrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  if(RandomInt(1)) {
    return ((64 + source + 8 * (RandomInt(2) - 1) + (RandomInt(2) - 1)) % 64);
  } else {
    return RandomInt(_nodes - 1);
  }
}

BadPermDFlyTrafficPattern::BadPermDFlyTrafficPattern(int nodes, int k, int n,
						     int xr)
  : DigitPermutationTrafficPattern(nodes, k, n, xr)
{

}

int BadPermDFlyTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int const grp_size_routers = 2 * (_xr * _k);
  int const grp_size_nodes = grp_size_routers * (_xr * _k);

  return ((RandomInt(grp_size_nodes - 1) + ((source / grp_size_nodes) + 1) * grp_size_nodes) % _nodes);
}

BadPermYarcTrafficPattern::BadPermYarcTrafficPattern(int nodes, int k, int n,
						     int xr)
  : DigitPermutationTrafficPattern(nodes, k, n, xr)
{

}

int BadPermYarcTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));
  int const row = source / (_xr * _k);
  return RandomInt((_xr * _k) - 1) * (_xr * _k) + row;
}

HotSpotTrafficPattern::HotSpotTrafficPattern(int nodes, vector<int> hotspots,
					     vector<int> rates)
  : TrafficPattern(nodes), _hotspots(hotspots), _rates(rates), _max_val(-1)
{
  assert(!_hotspots.empty());
  size_t const size = _hotspots.size();
  _rates.resize(size, _rates.empty() ? 1 : _rates.back());
  for(size_t i = 0; i < size; ++i) {
    int const hotspot = _hotspots[i];
    assert((hotspot >= 0) && (hotspot < _nodes));
    int const rate = _rates[i];
    assert(rate >= 0);
    _max_val += rate;
  }
}

int HotSpotTrafficPattern::dest(int source)
{
  assert((source >= 0) && (source < _nodes));

  int pct = RandomInt(_max_val);

  for(size_t i = 0; i < (_hotspots.size() - 1); ++i) {
    int const limit = _rates[i];
    if(limit > pct) {
      return _hotspots[i];
    } else {
      pct -= limit;
    }
  }
  assert(_rates.back() > pct);
  return _hotspots.back();
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of mhome.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "applicationpackagemonitor.h"
#include "launcherdatastore.h"
#include <QDir>
#include <QDBusConnection>
#include <mdesktopentry.h>
#include <mfiledatastore.h>
#include <msubdatastore.h>

static const QString PACKAGE_MANAGER_DBUS_SERVICE="com.nokia.package_manager";
static const QString PACKAGE_MANAGER_DBUS_PATH="/com/nokia/package_manager";
static const QString PACKAGE_MANAGER_DBUS_INTERFACE="com.nokia.package_manager";

static const QString OPERATION_INSTALL = "Install";
static const QString OPERATION_UNINSTALL = "Uninstall";
static const QString OPERATION_REFRESH = "Refresh";
static const QString OPERATION_UPGRADE = "Upgrade";

static const QString DESKTOPENTRY_PREFIX = "DesktopEntries";
static const QString PACKAGE_PREFIX = "Packages/";
static const QString INSTALLER_EXTRA = "installer-extra/";

static const QString CONFIG_PATH = "/.config/meegotouchhome";

static const QString PACKAGE_STATE_INSTALLED = "installed";
static const QString PACKAGE_STATE_INSTALLABLE = "installable";
static const QString PACKAGE_STATE_BROKEN = "broken";
static const QString PACKAGE_STATE_UPDATEABLE = "updateable";
static const QString PACKAGE_STATE_INSTALLING ="installing";
static const QString PACKAGE_STATE_DOWNLOADING ="downloading";

static const QString DESKTOP_ENTRY_KEY_PACKAGE_STATE = "PackageState";
static const QString DESKTOP_ENTRY_KEY_PACKAGE_HAD_ERROR = "PackageHadError";
static const QString DESKTOP_ENTRY_KEY_PACKAGE_NAME = "Package";
static const QString DESKTOP_ENTRY_GROUP_MEEGO = "X-MeeGo";

class ApplicationPackageMonitor::ExtraDirWatcher : public LauncherDataStore
{
public:
    ExtraDirWatcher(MDataStore *dataStore, const QStringList &directories);
    ~ExtraDirWatcher();

protected:
    virtual bool isDesktopEntryValid(const MDesktopEntry &entry, const QStringList &acceptedTypes);
};

ApplicationPackageMonitor::ApplicationPackageMonitor()
: con(QDBusConnection::systemBus())
{
    con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "download_progress",
                    this, SLOT(packageDownloadProgress(const QString&, const QString&, const QString&, int, int)));
    con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_started",
                    this, SLOT(packageOperationStarted(const QString&, const QString&, const QString&)));
    con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_progress",
                    this, SLOT(packageOperationProgress(const QString&, const QString &, const QString&, int)));
    con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_complete",
                    this, SLOT(packageOperationComplete(const QString&, const QString&, const QString&, const QString&, bool)));

    QString configPath = QDir::homePath() + CONFIG_PATH;

    if (!QDir::root().exists(configPath)) {
        QDir::root().mkpath(configPath);
    }

    QString dataStoreFileName = configPath + "/applicationpackage.data";

    dataStore = new MFileDataStore(dataStoreFileName);

    // ExtraDirWatcher takes ownership of dataStore
    extraDirWatcher = QSharedPointer<ExtraDirWatcher>(new ExtraDirWatcher(dataStore, QStringList() << (APPLICATIONS_DIRECTORY+INSTALLER_EXTRA)));

    connect(extraDirWatcher.data(), SIGNAL(desktopEntryAdded(QString)), this, SLOT(updatePackageState(QString)), Qt::UniqueConnection);
    connect(extraDirWatcher.data(), SIGNAL(desktopEntryChanged(QString)), this, SLOT(updatePackageState(QString)), Qt::UniqueConnection);
    connect(extraDirWatcher.data(), SIGNAL(desktopEntryRemoved(QString)), this, SLOT(packageRemoved(QString)), Qt::UniqueConnection);
}

ApplicationPackageMonitor::~ApplicationPackageMonitor()
{
}

void ApplicationPackageMonitor::packageRemoved(const QString &desktopEntryPath)
{
    QString packageKey;

    foreach(const QString &pkgKey, dataStore->allKeys()) {
        if(pkgKey.contains(PACKAGE_PREFIX)) {
            if(dataStore->value(pkgKey).toString() == desktopEntryPath) {
                packageKey = pkgKey;
                break;
            }
        }
    }

    dataStore->remove(DESKTOPENTRY_PREFIX+desktopEntryPath);
    dataStore->remove(packageKey);
    activePackages.remove(packageKey.remove(PACKAGE_PREFIX));

    emit installExtraEntryRemoved(desktopEntryPath);
}

void ApplicationPackageMonitor::updatePackageStates()
{
    QStringList keyList(dataStore->allKeys());

    foreach (QString key, keyList) {
        if (key.contains(PACKAGE_PREFIX)) {
            QString desktopEntryPath = dataStore->value(key).toString();
            QString state = dataStore->value(DESKTOPENTRY_PREFIX + desktopEntryPath).toString();
            if (state == PACKAGE_STATE_BROKEN) {
                // emit operation error for a broken package
                emit operationError(desktopEntryPath, QString());
            } else if(state == PACKAGE_STATE_DOWNLOADING) {
                emit downloadProgress(desktopEntryPath, 0, 0);
            } else if(state == PACKAGE_STATE_INSTALLING) {
                emit installProgress(desktopEntryPath, 0);
            }
        }
    }
}

ApplicationPackageMonitor::PackageProperties &ApplicationPackageMonitor::activePackageProperties(const QString packageName)
{
    if (!activePackages.contains(packageName)) {
        // Set the desktopEntryName if already known
        activePackages[packageName].desktopEntryName = desktopEntryName(packageName);
    }

    return activePackages[packageName];
}

void ApplicationPackageMonitor::packageDownloadProgress(const QString &operation,
                                    const QString &packageName,
                                    const QString &packageVersion,
                                    int already, int total)
{
    Q_UNUSED(operation)
    Q_UNUSED(packageVersion)

    PackageProperties &properties = activePackageProperties(packageName);

    if (isValidOperation(properties, operation)) {
        emit downloadProgress(properties.desktopEntryName, already, total);
    }

    storePackageState(packageName, PACKAGE_STATE_DOWNLOADING);
}

void ApplicationPackageMonitor::packageOperationStarted(const QString &operation,
                                const QString &packageName,
                                const QString &version)
{
    Q_UNUSED(operation)
    Q_UNUSED(packageName)
    Q_UNUSED(version)
}

void ApplicationPackageMonitor::packageOperationProgress(const QString &operation,
                                const QString &packageName,
                                const QString &packageVersion,
                                int percentage)
{
    Q_UNUSED(packageVersion)

    PackageProperties &properties = activePackageProperties(packageName);

    if (isValidOperation(properties, operation)) {
        properties.installing = true;
        emit installProgress(properties.desktopEntryName, percentage);
        storePackageState(packageName, PACKAGE_STATE_INSTALLING);
    }
}

void ApplicationPackageMonitor::packageOperationComplete(const QString &operation,
                                const QString &packageName,
                                const QString &packageVersion,
                                const QString &error,
                                bool need_reboot)
{
    Q_UNUSED(packageVersion)
    Q_UNUSED(need_reboot)

    PackageProperties &properties = activePackageProperties(packageName);

    if (!isValidOperation(properties, operation)) {
        return;
    }

    if (!error.isEmpty()) {
        if (properties.installing) {
            emit operationError(properties.desktopEntryName, error);
            storePackageState(packageName, PACKAGE_STATE_BROKEN);
        }
        else {
            // Downloading
            MDesktopEntry entry(properties.desktopEntryName);
            QString packageState = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE);
            if (packageState == PACKAGE_STATE_INSTALLED || packageState == PACKAGE_STATE_UPDATEABLE) {
                // Application is previously installed. Downloading update failed but application still usable.
                emit operationSuccess(properties.desktopEntryName.replace(INSTALLER_EXTRA, QString()));
                storePackageState(packageName, packageState);
            } else {
                emit operationError(properties.desktopEntryName, error);
                storePackageState(packageName, PACKAGE_STATE_BROKEN);
            }
        }
    } else {
        emit operationSuccess(properties.desktopEntryName.replace(INSTALLER_EXTRA, QString()));
        storePackageState(packageName, PACKAGE_STATE_INSTALLED);
    }

    activePackages.remove(packageName);
}

void ApplicationPackageMonitor::storePackageState(const QString& packageName, const QString& state)
{
    QString path = dataStore->value(PACKAGE_PREFIX + packageName).toString();
    extraDirWatcher->updateDataForDesktopEntry(path, state);
}

bool ApplicationPackageMonitor::isValidOperation(const PackageProperties &properties, const QString &operation)
{
    if ((operation.compare(OPERATION_INSTALL, Qt::CaseInsensitive) == 0 ||
           operation.compare(OPERATION_UPGRADE, Qt::CaseInsensitive) == 0 ) &&
        !properties.desktopEntryName.isEmpty() ) {
         return true;
    } else {
         return false;
    }
}

void ApplicationPackageMonitor::updatePackageState(const QString &desktopEntryPath)
{
    MDesktopEntry entry(desktopEntryPath);

    QString packageName = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_NAME);
    QString packageState = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE);
    bool packageHadError = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_HAD_ERROR) == "true";

    if (packageHadError)
      packageState = PACKAGE_STATE_BROKEN;

    if (!packageName.isEmpty()) {
        QString pkgKey = PACKAGE_PREFIX+packageName;

        if (packageState == PACKAGE_STATE_BROKEN) {
            // emit operation error for a broken package
            emit operationError(desktopEntryPath, QString());
        }

        dataStore->createValue(pkgKey, desktopEntryPath);

        if (activePackages.contains(packageName)) {
            // Package is being installed, add the desktop entry path directly
            activePackages[packageName].desktopEntryName = desktopEntryPath;
        }
    }

    extraDirWatcher->updateDataForDesktopEntry(desktopEntryPath, packageState);
}

QString ApplicationPackageMonitor::desktopEntryName(const QString &packageName)
{
    QString pkgKey = PACKAGE_PREFIX+packageName;

    if (!dataStore->contains(pkgKey)) {
        // Package not installed
        return QString();
    }

    if (!QFile::exists(dataStore->value(pkgKey).toString())) {
        // The extra desktop file doesn't exist anymore, the package has been uninstalled
        dataStore->remove(pkgKey);
        return QString();
    }

    return dataStore->value(pkgKey).toString();
}

ApplicationPackageMonitor::ExtraDirWatcher::ExtraDirWatcher(MDataStore *dataStore, const QStringList &directories) :
    LauncherDataStore(dataStore, directories)
{
}

ApplicationPackageMonitor::ExtraDirWatcher::~ExtraDirWatcher()
{
}

bool ApplicationPackageMonitor::ExtraDirWatcher::isDesktopEntryValid(const MDesktopEntry &entry, const QStringList &acceptedTypes)
{
    Q_UNUSED(acceptedTypes);

    return entry.contains(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_NAME)
        && entry.contains(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE);
}
<commit_msg>Changes: Fixing a foreach const from Krazy findings<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of mhome.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "applicationpackagemonitor.h"
#include "launcherdatastore.h"
#include <QDir>
#include <QDBusConnection>
#include <mdesktopentry.h>
#include <mfiledatastore.h>
#include <msubdatastore.h>

static const QString PACKAGE_MANAGER_DBUS_SERVICE="com.nokia.package_manager";
static const QString PACKAGE_MANAGER_DBUS_PATH="/com/nokia/package_manager";
static const QString PACKAGE_MANAGER_DBUS_INTERFACE="com.nokia.package_manager";

static const QString OPERATION_INSTALL = "Install";
static const QString OPERATION_UNINSTALL = "Uninstall";
static const QString OPERATION_REFRESH = "Refresh";
static const QString OPERATION_UPGRADE = "Upgrade";

static const QString DESKTOPENTRY_PREFIX = "DesktopEntries";
static const QString PACKAGE_PREFIX = "Packages/";
static const QString INSTALLER_EXTRA = "installer-extra/";

static const QString CONFIG_PATH = "/.config/meegotouchhome";

static const QString PACKAGE_STATE_INSTALLED = "installed";
static const QString PACKAGE_STATE_INSTALLABLE = "installable";
static const QString PACKAGE_STATE_BROKEN = "broken";
static const QString PACKAGE_STATE_UPDATEABLE = "updateable";
static const QString PACKAGE_STATE_INSTALLING ="installing";
static const QString PACKAGE_STATE_DOWNLOADING ="downloading";

static const QString DESKTOP_ENTRY_KEY_PACKAGE_STATE = "PackageState";
static const QString DESKTOP_ENTRY_KEY_PACKAGE_HAD_ERROR = "PackageHadError";
static const QString DESKTOP_ENTRY_KEY_PACKAGE_NAME = "Package";
static const QString DESKTOP_ENTRY_GROUP_MEEGO = "X-MeeGo";

class ApplicationPackageMonitor::ExtraDirWatcher : public LauncherDataStore
{
public:
    ExtraDirWatcher(MDataStore *dataStore, const QStringList &directories);
    ~ExtraDirWatcher();

protected:
    virtual bool isDesktopEntryValid(const MDesktopEntry &entry, const QStringList &acceptedTypes);
};

ApplicationPackageMonitor::ApplicationPackageMonitor()
: con(QDBusConnection::systemBus())
{
    con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "download_progress",
                    this, SLOT(packageDownloadProgress(const QString&, const QString&, const QString&, int, int)));
    con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_started",
                    this, SLOT(packageOperationStarted(const QString&, const QString&, const QString&)));
    con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_progress",
                    this, SLOT(packageOperationProgress(const QString&, const QString &, const QString&, int)));
    con.connect(QString(),PACKAGE_MANAGER_DBUS_PATH, PACKAGE_MANAGER_DBUS_INTERFACE, "operation_complete",
                    this, SLOT(packageOperationComplete(const QString&, const QString&, const QString&, const QString&, bool)));

    QString configPath = QDir::homePath() + CONFIG_PATH;

    if (!QDir::root().exists(configPath)) {
        QDir::root().mkpath(configPath);
    }

    QString dataStoreFileName = configPath + "/applicationpackage.data";

    dataStore = new MFileDataStore(dataStoreFileName);

    // ExtraDirWatcher takes ownership of dataStore
    extraDirWatcher = QSharedPointer<ExtraDirWatcher>(new ExtraDirWatcher(dataStore, QStringList() << (APPLICATIONS_DIRECTORY+INSTALLER_EXTRA)));

    connect(extraDirWatcher.data(), SIGNAL(desktopEntryAdded(QString)), this, SLOT(updatePackageState(QString)), Qt::UniqueConnection);
    connect(extraDirWatcher.data(), SIGNAL(desktopEntryChanged(QString)), this, SLOT(updatePackageState(QString)), Qt::UniqueConnection);
    connect(extraDirWatcher.data(), SIGNAL(desktopEntryRemoved(QString)), this, SLOT(packageRemoved(QString)), Qt::UniqueConnection);
}

ApplicationPackageMonitor::~ApplicationPackageMonitor()
{
}

void ApplicationPackageMonitor::packageRemoved(const QString &desktopEntryPath)
{
    QString packageKey;

    foreach(const QString &pkgKey, dataStore->allKeys()) {
        if(pkgKey.contains(PACKAGE_PREFIX)) {
            if(dataStore->value(pkgKey).toString() == desktopEntryPath) {
                packageKey = pkgKey;
                break;
            }
        }
    }

    dataStore->remove(DESKTOPENTRY_PREFIX+desktopEntryPath);
    dataStore->remove(packageKey);
    activePackages.remove(packageKey.remove(PACKAGE_PREFIX));

    emit installExtraEntryRemoved(desktopEntryPath);
}

void ApplicationPackageMonitor::updatePackageStates()
{
    QStringList keyList(dataStore->allKeys());

    foreach (const QString &key, keyList) {
        if (key.contains(PACKAGE_PREFIX)) {
            QString desktopEntryPath = dataStore->value(key).toString();
            QString state = dataStore->value(DESKTOPENTRY_PREFIX + desktopEntryPath).toString();
            if (state == PACKAGE_STATE_BROKEN) {
                // emit operation error for a broken package
                emit operationError(desktopEntryPath, QString());
            } else if(state == PACKAGE_STATE_DOWNLOADING) {
                emit downloadProgress(desktopEntryPath, 0, 0);
            } else if(state == PACKAGE_STATE_INSTALLING) {
                emit installProgress(desktopEntryPath, 0);
            }
        }
    }
}

ApplicationPackageMonitor::PackageProperties &ApplicationPackageMonitor::activePackageProperties(const QString packageName)
{
    if (!activePackages.contains(packageName)) {
        // Set the desktopEntryName if already known
        activePackages[packageName].desktopEntryName = desktopEntryName(packageName);
    }

    return activePackages[packageName];
}

void ApplicationPackageMonitor::packageDownloadProgress(const QString &operation,
                                    const QString &packageName,
                                    const QString &packageVersion,
                                    int already, int total)
{
    Q_UNUSED(operation)
    Q_UNUSED(packageVersion)

    PackageProperties &properties = activePackageProperties(packageName);

    if (isValidOperation(properties, operation)) {
        emit downloadProgress(properties.desktopEntryName, already, total);
    }

    storePackageState(packageName, PACKAGE_STATE_DOWNLOADING);
}

void ApplicationPackageMonitor::packageOperationStarted(const QString &operation,
                                const QString &packageName,
                                const QString &version)
{
    Q_UNUSED(operation)
    Q_UNUSED(packageName)
    Q_UNUSED(version)
}

void ApplicationPackageMonitor::packageOperationProgress(const QString &operation,
                                const QString &packageName,
                                const QString &packageVersion,
                                int percentage)
{
    Q_UNUSED(packageVersion)

    PackageProperties &properties = activePackageProperties(packageName);

    if (isValidOperation(properties, operation)) {
        properties.installing = true;
        emit installProgress(properties.desktopEntryName, percentage);
        storePackageState(packageName, PACKAGE_STATE_INSTALLING);
    }
}

void ApplicationPackageMonitor::packageOperationComplete(const QString &operation,
                                const QString &packageName,
                                const QString &packageVersion,
                                const QString &error,
                                bool need_reboot)
{
    Q_UNUSED(packageVersion)
    Q_UNUSED(need_reboot)

    PackageProperties &properties = activePackageProperties(packageName);

    if (!isValidOperation(properties, operation)) {
        return;
    }

    if (!error.isEmpty()) {
        if (properties.installing) {
            emit operationError(properties.desktopEntryName, error);
            storePackageState(packageName, PACKAGE_STATE_BROKEN);
        }
        else {
            // Downloading
            MDesktopEntry entry(properties.desktopEntryName);
            QString packageState = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE);
            if (packageState == PACKAGE_STATE_INSTALLED || packageState == PACKAGE_STATE_UPDATEABLE) {
                // Application is previously installed. Downloading update failed but application still usable.
                emit operationSuccess(properties.desktopEntryName.replace(INSTALLER_EXTRA, QString()));
                storePackageState(packageName, packageState);
            } else {
                emit operationError(properties.desktopEntryName, error);
                storePackageState(packageName, PACKAGE_STATE_BROKEN);
            }
        }
    } else {
        emit operationSuccess(properties.desktopEntryName.replace(INSTALLER_EXTRA, QString()));
        storePackageState(packageName, PACKAGE_STATE_INSTALLED);
    }

    activePackages.remove(packageName);
}

void ApplicationPackageMonitor::storePackageState(const QString& packageName, const QString& state)
{
    QString path = dataStore->value(PACKAGE_PREFIX + packageName).toString();
    extraDirWatcher->updateDataForDesktopEntry(path, state);
}

bool ApplicationPackageMonitor::isValidOperation(const PackageProperties &properties, const QString &operation)
{
    if ((operation.compare(OPERATION_INSTALL, Qt::CaseInsensitive) == 0 ||
           operation.compare(OPERATION_UPGRADE, Qt::CaseInsensitive) == 0 ) &&
        !properties.desktopEntryName.isEmpty() ) {
         return true;
    } else {
         return false;
    }
}

void ApplicationPackageMonitor::updatePackageState(const QString &desktopEntryPath)
{
    MDesktopEntry entry(desktopEntryPath);

    QString packageName = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_NAME);
    QString packageState = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE);
    bool packageHadError = entry.value(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_HAD_ERROR) == "true";

    if (packageHadError)
      packageState = PACKAGE_STATE_BROKEN;

    if (!packageName.isEmpty()) {
        QString pkgKey = PACKAGE_PREFIX+packageName;

        if (packageState == PACKAGE_STATE_BROKEN) {
            // emit operation error for a broken package
            emit operationError(desktopEntryPath, QString());
        }

        dataStore->createValue(pkgKey, desktopEntryPath);

        if (activePackages.contains(packageName)) {
            // Package is being installed, add the desktop entry path directly
            activePackages[packageName].desktopEntryName = desktopEntryPath;
        }
    }

    extraDirWatcher->updateDataForDesktopEntry(desktopEntryPath, packageState);
}

QString ApplicationPackageMonitor::desktopEntryName(const QString &packageName)
{
    QString pkgKey = PACKAGE_PREFIX+packageName;

    if (!dataStore->contains(pkgKey)) {
        // Package not installed
        return QString();
    }

    if (!QFile::exists(dataStore->value(pkgKey).toString())) {
        // The extra desktop file doesn't exist anymore, the package has been uninstalled
        dataStore->remove(pkgKey);
        return QString();
    }

    return dataStore->value(pkgKey).toString();
}

ApplicationPackageMonitor::ExtraDirWatcher::ExtraDirWatcher(MDataStore *dataStore, const QStringList &directories) :
    LauncherDataStore(dataStore, directories)
{
}

ApplicationPackageMonitor::ExtraDirWatcher::~ExtraDirWatcher()
{
}

bool ApplicationPackageMonitor::ExtraDirWatcher::isDesktopEntryValid(const MDesktopEntry &entry, const QStringList &acceptedTypes)
{
    Q_UNUSED(acceptedTypes);

    return entry.contains(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_NAME)
        && entry.contains(DESKTOP_ENTRY_GROUP_MEEGO, DESKTOP_ENTRY_KEY_PACKAGE_STATE);
}
<|endoftext|>


<commit_before>#include <QApplication>
#include <QStringList>
#include "qargparser.h"

QString QArgByKey(QString key, QChar sep)
{
    if(qApp->arguments().size() < 2)
        return QString::null;
    bool sepd = sep != QChar('\0');
    int pos = sepd ? qApp->arguments().indexOf(QRegExp('^'+ key + sep +"\\S*")) : qApp->arguments().indexOf(QRegExp(key));
    return sepd?qApp->arguments().at(pos).split(sep).at(1)
    :(++pos < qApp->arguments().size() ? qApp->arguments().at(pos) : QString::null);
}

<commit_msg>Algorithm correction<commit_after>#include <QApplication>
#include <QStringList>
#include "qargparser.h"

QString QArgByKey(QString key, QChar sep )
{
    bool sepd=sep!=QChar('\0');
    int pos=sepd?qApp->arguments().indexOf(QRegExp('^'+key+sep+"\\S*")):qApp->arguments().indexOf(QRegExp(key));
    return pos==-1?QString::null:
    (sepd?qApp->arguments().at(pos).split(sep).at(1):(++pos<qApp->arguments().size()?qApp->arguments().at(pos):QString::null));
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#include <vector>
#include <iomanip>
#include <cmath>
#include <list>
#include <bitset>

using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, double>pdd;

const double eps = 1e-6;
const ll  LINF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const double FINF = 1e18;

#define x first
#define y second

#define REP(i,j,k) for(int i =(j);i<=(k);i++)
#define REPD(i,j,k) for(int i =(j);i>=(k);i--)
#define print(x) cout<<(x)<<endl;
#define IOS ios::sync_with_stdio(0);cin.tie(0);

int fa[10010],le[30],bgn[30];

int n, a[10010],b[10010],la = 0,lb = 0;

int find(int x)
{
    return (x==fa[x]?x:find(fa[x]));
}

void Union(int m, int n)
{
    m = find(m);
    n = find(n);
    if(m!=n)
        fa[m] = n;
}

void Init(){
	scanf("%d",&n);
    scanf("%d",&le[0]);
    bgn[0] = 2;

    REP(i,1,n-1)
    {
        scanf("%d",&le[i]);
        bgn[i] = bgn[i-1] + le[i-1];
    }

    char ch;
    getchar();
    while((ch= getchar())!='=')
        if(ch=='0' || ch=='1')
            a[la++] = ch-'0';
        else
            REP(i,0,le[ch-'a']-1)
                a[la++] = bgn[ch-'a'] + i;

    while((ch= getchar())!='\n' )
        if(ch=='0' || ch=='1')
            b[lb++] = ch-'0';
        else
         	REP(i,0,le[ch-'a']-1)
                b[lb++] = bgn[ch-'a'] + i;

	return ;
}

void Solve(){
	if(la!=lb)
    {
       print(0);
        return ;
    }

    REP(i,0,bgn[n-1]+le[n-1]-1)
        fa[i] = i;

    REP(i,0,la-1)
    {
        if(a[i]+b[i]==1)
        {
            print(0);
            return ;
        }

        Union(a[i],b[i]);
    }

    int ans = 0;
    REP(i,0,bgn[n-1]+le[n-1]-1)
        if(fa[i]==i) ans++;
    if(ans==0)
    	printf("0\n");
   	else if(ans==1)
   		printf("0\n");
   	else{
   		long long  a=1;
    	printf("%lld\n",1<<(62));
   	}

	return ;
}

int main(){
#ifdef LOCAL
	freopen("uoj1138.in","r",stdin);
#endif

	Init(),Solve();
	return 0;
}<commit_msg>update uoj1138<commit_after>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cstring>
#include <string>
#include <vector>
#include <iomanip>
#include <cmath>
#include <list>
#include <bitset>

using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pair<int, int>pii;
typedef pair<ll, ll>pll;
typedef pair<double, double>pdd;

const double eps = 1e-6;
const ll  LINF = 0x3f3f3f3f3f3f3f3fLL;
const int INF = 0x3f3f3f3f;
const double FINF = 1e18;

#define x first
#define y second

#define REP(i,j,k) for(int i =(j);i<=(k);i++)
#define REPD(i,j,k) for(int i =(j);i>=(k);i--)
#define print(x) cout<<(x)<<endl;
#define IOS ios::sync_with_stdio(0);cin.tie(0);

int fa[10010],le[30],bgn[30];

int n, a[10010],b[10010],la = 0,lb = 0;

int find(int x)
{
    return (x==fa[x]?x:find(fa[x]));
}

void Union(int m, int n)
{
    m = find(m);
    n = find(n);
    if(m!=n)
        fa[m] = n;
}

void Init(){
	scanf("%d",&n);
    scanf("%d",&le[0]);
    bgn[0] = 2;

    REP(i,1,n-1)
    {
        scanf("%d",&le[i]);
        bgn[i] = bgn[i-1] + le[i-1];
    }

    char ch;
    getchar();
    while((ch= getchar())!='=')
        if(ch=='0' || ch=='1')
            a[la++] = ch-'0';
        else
            REP(i,0,le[ch-'a']-1)
                a[la++] = bgn[ch-'a'] + i;

    while((ch= getchar())!='\n' )
        if(ch=='0' || ch=='1')
            b[lb++] = ch-'0';
        else
         	REP(i,0,le[ch-'a']-1)
                b[lb++] = bgn[ch-'a'] + i;

	return ;
}

void Solve(){
	if(la!=lb)
    {
       print(0);
        return ;
    }

    REP(i,0,bgn[n-1]+le[n-1]-1)
        fa[i] = i;

    REP(i,0,la-1)
    {
        if(a[i]+b[i]==1)
        {
            print(0);
            return ;
        }

        Union(a[i],b[i]);
    }

    int ans = 0;
    REP(i,0,bgn[n-1]+le[n-1]-1)
        if(fa[i]==i) ans++;
    if(ans==0)
    	printf("0\n");
   	else if(ans==1)
   		printf("0\n");
   	else{
   		long long  a=1;
    	printf("%lld\n",a<<(62));
   	}

	return ;
}

int main(){
#ifdef LOCAL
	freopen("uoj1138.in","r",stdin);
#endif

	Init(),Solve();
	return 0;
}<|endoftext|>


<commit_before>#include "stdio.h"
#include "stdlib.h"
#include <iostream>
#define  MAXSTRLEN  255                   // 用户可在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN+1];	// 0号单元存放串的长度

void get_next(SString T,int next[]){
// 算法4.7
// 求模式串T的next函数值并存入数组next
   // 请补全代码
	int i,j;
	next[1]=0;
	j=0;
	while(i<T[0]){

		if(j == 0 || T[i]==T[j]){
			++i;
			++j;
			next[i]=j;}
		else{
			j=next[j];
		}
	}
}
int  main(){
	int next[MAXSTRLEN];
	SString S;
	int n,i,j;
	char ch;
	scanf("%d",&n);    // 指定要验证NEXT值的字符串个数
	ch=getchar();
	for(i=1;i<=n;i++)
	{
		ch=getchar();
		for(j=1;j<=MAXSTRLEN&&(ch!='\n');j++)    // 录入字符串
		{
			S[j]=ch;
			ch=getchar();
		}
		S[0]=j-1;    // S[0]用于存储字符串中字符个数
		printf("%s",S+1);
		get_next(S,next);
		printf("NEXT J is:");
		for(j=1;j<=S[0];j++)
			printf("%d",next[j]);
		printf("\n");
	}
}

<commit_msg>update uoj8591<commit_after>#include "stdio.h"
#include "stdlib.h"
#include <iostream>
#define  MAXSTRLEN  255                   // 用户可在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN+1];	// 0号单元存放串的长度

void get_next(SString T,int next[]){
// 算法4.7
// 求模式串T的next函数值并存入数组next
   // 请补全代码
	int i,j;
	next[1]=0;
	j=0;
	while(i<T[0]){

		if(j == 0 || T[i]==T[j]){
			++i;
			++j;
			next[i]=j;}
		else{
			j=next[j];
		}
	}
}
int  main(){
	int next[MAXSTRLEN];
	SString S;
	int n,i,j;
	char ch;
	scanf("%d",&n);    // 指定要验证NEXT值的字符串个数
	ch=getchar();
	for(i=1;i<=n;i++)
	{
		ch=getchar();
		for(j=1;j<=MAXSTRLEN&&(ch!='\n');j++)    // 录入字符串
		{
			S[j]=ch;
			ch=getchar();
		}
		S[0]=j-1;    // S[0]用于存储字符串中字符个数
		//printf("%s",S+1);
		get_next(S,next);
		printf("NEXT J is:");
		for(j=1;j<=S[0];j++)
			printf("%d",next[j]);
		printf("\n");
	}
}

<|endoftext|>