/***************************************************************************//**
 *
 * \file support/atom.cpp
 *
 * \author David Juhasz (david.juhasz@tuwien.ac.at)
 *
 * \date 2017
 *
 * \brief Implementation of non-static part of atom facilities of
 *        rosa/support/atom.hpp.
 *
 * \note This implementation is based on the `atom` implementation of CAF.
 * \todo Check license.
 *
 ******************************************************************************/

#include "rosa/support/atom.hpp"

#include <cstring>

namespace rosa {

std::string to_string(const AtomValue &What) {
  auto X = static_cast<atom_t>(What);
  std::string S;
  S.reserve(MaxAtomLength + 1);
  // Don't read characters before we found the leading 0xF.
  // First four bits set?
  bool ReadChars = ((X & 0xF000000000000000) >> 60) == 0xF;
  uint64_t Mask = 0x0FC0000000000000;
  for (int BitShift = 54; BitShift >= 0; BitShift -= 6, Mask >>= 6) {
    if (ReadChars) {
      S += AtomDecodingTable[(X & Mask) >> BitShift];
    } else if (((X & Mask) >> BitShift) == 0xF) {
      ReadChars = true;
    }
  }
  return S;
}

AtomValue atom_from_string(const std::string &S) {
  if (S.size() > MaxAtomLength) {
    return atom("");
  }
  char AtomBuf[MaxAtomLength + 1];
  std::memcpy(AtomBuf, S.c_str(), S.size());
  AtomBuf[S.size()] = '\0';
  return atom(AtomBuf);
}

} // End namespace rosa

