<commit_before>#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkResampleImageFilter.h"
#include "itkIdentityTransform.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkRecursiveGaussianImageFilter.h"
#include "itkCastImageFilter.h"

using namespace std;

int main( int argc, char * argv[] )
{
  if( argc < 3 ) {
    cerr << "Usage: " << endl;
    cerr << argv[0] << "  inputImageFile  outputImageFile" << endl;
    return EXIT_FAILURE;
  }

  const     unsigned int   Dimension = 2;

  typedef   unsigned char  InputPixelType;
  typedef   float          InternalPixelType;
  typedef   unsigned short OutputPixelType;

  typedef itk::Image< InputPixelType,    Dimension > InputImageType;
  typedef itk::Image< InternalPixelType, Dimension > InternalImageType;
  typedef itk::Image< OutputPixelType,   Dimension > OutputImageType;

  typedef itk::ImageFileReader< InputImageType  > ReaderType;
  typedef itk::ImageFileWriter< OutputImageType > WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( argv[1] );
  writer->SetFileName( argv[2] );

  const double factor = 128.0;

  try {
    reader->Update();
  }
  catch( itk::ExceptionObject & excep ) {
    cerr << "Exception caught!" << endl;
    cerr << excep << endl;
  }

  InputImageType::ConstPointer inputImage = reader->GetOutput();

  typedef itk::CastImageFilter< InputImageType, InternalImageType > CastFilterType;

  CastFilterType::Pointer caster = CastFilterType::New();

  caster->SetInput( inputImage );

  typedef itk::RecursiveGaussianImageFilter< InternalImageType,
                                             InternalImageType > GaussianFilterType;

  GaussianFilterType::Pointer smootherX = GaussianFilterType::New();
  GaussianFilterType::Pointer smootherY = GaussianFilterType::New();

  smootherX->SetInput( caster->GetOutput() );
  smootherY->SetInput( smootherX->GetOutput() );

  // The Sigma values to use in the smoothing filters is computed based on the
  // pixel spacings of the input image and the factors provided as arguments.

  const InputImageType::SpacingType& inputSpacing = inputImage->GetSpacing();

  const double sigmaX = inputSpacing[0] * factor;
  const double sigmaY = inputSpacing[1] * factor;

  smootherX->SetSigma( sigmaX );
  smootherY->SetSigma( sigmaY );

  smootherX->SetDirection( 0 );
  smootherY->SetDirection( 1 );

  smootherX->SetNormalizeAcrossScale( false );
  smootherY->SetNormalizeAcrossScale( false );

  typedef itk::ResampleImageFilter< InternalImageType, OutputImageType >  ResampleFilterType;

  ResampleFilterType::Pointer resampler = ResampleFilterType::New();

  typedef itk::IdentityTransform< double, Dimension >  TransformType;

  TransformType::Pointer transform = TransformType::New();
  transform->SetIdentity();
  resampler->SetTransform( transform );

  typedef itk::LinearInterpolateImageFunction< InternalImageType, double >  InterpolatorType;
  InterpolatorType::Pointer interpolator = InterpolatorType::New();
  resampler->SetInterpolator( interpolator );

  resampler->SetDefaultPixelValue( 0 );

  OutputImageType::SpacingType spacing;

  spacing[0] = inputSpacing[0] * factor;
  spacing[1] = inputSpacing[1] * factor;

  resampler->SetOutputSpacing( spacing );
  resampler->SetOutputOrigin( inputImage->GetOrigin() );
  resampler->SetOutputDirection( inputImage->GetDirection() );

  InputImageType::SizeType   inputSize = inputImage->GetLargestPossibleRegion().GetSize();

  typedef InputImageType::SizeType::SizeValueType SizeValueType;

  InputImageType::SizeType size;

  size[0] = static_cast< SizeValueType >( inputSize[0] / factor );
  size[1] = static_cast< SizeValueType >( inputSize[1] / factor );

  resampler->SetSize( size );

  resampler->SetInput( smootherY->GetOutput() );

  writer->SetInput( resampler->GetOutput() );

  try {
    writer->Update();
  }
  catch( itk::ExceptionObject & excep ) {
    cerr << "Exception caught!" << endl;
    cerr << excep << endl;
  }

  return EXIT_SUCCESS;
}
<commit_msg>Changed the downsampling factor in ShrinkImage.cxx from 128.0 to 64.0.<commit_after>#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkResampleImageFilter.h"
#include "itkIdentityTransform.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkRecursiveGaussianImageFilter.h"
#include "itkCastImageFilter.h"

using namespace std;

int main( int argc, char * argv[] )
{
  if( argc < 3 ) {
    cerr << "Usage: " << endl;
    cerr << argv[0] << "  inputImageFile  outputImageFile" << endl;
    return EXIT_FAILURE;
  }

  const     unsigned int   Dimension = 2;

  typedef   unsigned char  InputPixelType;
  typedef   float          InternalPixelType;
  typedef   unsigned short OutputPixelType;

  typedef itk::Image< InputPixelType,    Dimension > InputImageType;
  typedef itk::Image< InternalPixelType, Dimension > InternalImageType;
  typedef itk::Image< OutputPixelType,   Dimension > OutputImageType;

  typedef itk::ImageFileReader< InputImageType  > ReaderType;
  typedef itk::ImageFileWriter< OutputImageType > WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( argv[1] );
  writer->SetFileName( argv[2] );

  const double factor = 64.0;

  try {
    reader->Update();
  }
  catch( itk::ExceptionObject & excep ) {
    cerr << "Exception caught!" << endl;
    cerr << excep << endl;
  }

  InputImageType::ConstPointer inputImage = reader->GetOutput();

  typedef itk::CastImageFilter< InputImageType, InternalImageType > CastFilterType;

  CastFilterType::Pointer caster = CastFilterType::New();

  caster->SetInput( inputImage );

  typedef itk::RecursiveGaussianImageFilter< InternalImageType, InternalImageType > GaussianFilterType;

  GaussianFilterType::Pointer smootherX = GaussianFilterType::New();
  GaussianFilterType::Pointer smootherY = GaussianFilterType::New();

  smootherX->SetInput( caster->GetOutput() );
  smootherY->SetInput( smootherX->GetOutput() );

  // The Sigma values to use in the smoothing filters is computed based on the
  // pixel spacings of the input image and the factors provided as arguments.

  const InputImageType::SpacingType& inputSpacing = inputImage->GetSpacing();

  const double sigmaX = inputSpacing[0] * factor;
  const double sigmaY = inputSpacing[1] * factor;

  smootherX->SetSigma( sigmaX );
  smootherY->SetSigma( sigmaY );

  smootherX->SetDirection( 0 );
  smootherY->SetDirection( 1 );

  smootherX->SetNormalizeAcrossScale( false );
  smootherY->SetNormalizeAcrossScale( false );

  typedef itk::ResampleImageFilter< InternalImageType, OutputImageType >  ResampleFilterType;

  ResampleFilterType::Pointer resampler = ResampleFilterType::New();

  typedef itk::IdentityTransform< double, Dimension >  TransformType;

  TransformType::Pointer transform = TransformType::New();
  transform->SetIdentity();
  resampler->SetTransform( transform );

  typedef itk::LinearInterpolateImageFunction< InternalImageType, double >  InterpolatorType;
  InterpolatorType::Pointer interpolator = InterpolatorType::New();
  resampler->SetInterpolator( interpolator );

  resampler->SetDefaultPixelValue( 0 );

  OutputImageType::SpacingType spacing;

  spacing[0] = inputSpacing[0] * factor;
  spacing[1] = inputSpacing[1] * factor;

  resampler->SetOutputSpacing( spacing );
  resampler->SetOutputOrigin( inputImage->GetOrigin() );
  resampler->SetOutputDirection( inputImage->GetDirection() );

  InputImageType::SizeType   inputSize = inputImage->GetLargestPossibleRegion().GetSize();

  typedef InputImageType::SizeType::SizeValueType SizeValueType;

  InputImageType::SizeType size;

  size[0] = static_cast< SizeValueType >( inputSize[0] / factor );
  size[1] = static_cast< SizeValueType >( inputSize[1] / factor );

  resampler->SetSize( size );

  resampler->SetInput( smootherY->GetOutput() );

  writer->SetInput( resampler->GetOutput() );

  try {
    writer->Update();
  }
  catch( itk::ExceptionObject & excep ) {
    cerr << "Exception caught!" << endl;
    cerr << excep << endl;
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * SessionEnvironment.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "SessionEnvironment.hpp"
#include "EnvironmentMonitor.hpp"

#include <algorithm>

#include <core/Exec.hpp>

#define INTERNAL_R_FUNCTIONS
#include <r/RSexp.hpp>
#include <r/RExec.hpp>
#include <r/session/RSession.hpp>
#include <r/RInterface.hpp>
#include <session/SessionModuleContext.hpp>
#include <session/SessionSourceDatabase.hpp>
#include <boost/foreach.hpp>

#include "EnvironmentUtils.hpp"

#define TOP_FUNCTION 1

using namespace core ;

namespace session {
namespace modules {
namespace environment {

EnvironmentMonitor s_environmentMonitor;

namespace {

bool handleRBrowseEnv(const core::FilePath& filePath)
{
   if (filePath.filename() == "wsbrowser.html")
   {
      module_context::showContent("R objects", filePath);
      return true;
   }
   else
   {
      return false;
   }
}

SEXP getOriginalFunctionCallObject(const RCNTXT* pContext)
{
   SEXP callObject = pContext->callfun;
   // enabling tracing on a function turns it into an S4 object with an
   // 'original' slot that includes the function's original contents. use
   // this instead if it's set up. (consider: is it safe to assume that S4
   // objects here are always traced functions, or do we need to compare classes
   // to be safe?)
   if (Rf_isS4(callObject))
   {
      callObject = r::sexp::getAttrib(callObject, "original");
   }
   return callObject;
}

Error getFileNameFromContext(const RCNTXT* pContext,
                             std::string* pFileName)
{
   SEXP srcref = pContext->srcref;
   return r::exec::RFunction(".rs.sourceFileFromRef", srcref)
                 .call(pFileName);
}

SEXP sourceRefsOfContext(const RCNTXT* pContext)
{
   return r::sexp::getAttrib(getOriginalFunctionCallObject(pContext), "srcref");
}

bool hasSourceRefs(const RCNTXT* pContext)
{
   SEXP srcref = sourceRefsOfContext(pContext);
   return srcref != NULL && TYPEOF(srcref) != NILSXP;
}

bool isDebugHiddenContext(RCNTXT* pContext)
{
   SEXP hideFlag = r::sexp::getAttrib(pContext->callfun, "hideFromDebugger");
   return TYPEOF(hideFlag) != NILSXP && r::sexp::asLogical(hideFlag);
}

// given a context from the context stack, indicate whether it should be emitted
// to the callstack.
bool isPrintableContext(RCNTXT* pContext)
{
   if (pContext->callflag & CTXT_FUNCTION)
   {
      if (isDebugHiddenContext(pContext))
      {
         // hidden function
         return false;
      }
      // printable function
      return true;
   }
   // not a function at all
   return false;
}

// return the function context at the given depth
RCNTXT* getFunctionContext(const int depth,
                           bool findUserCode = false,
                           int* pFoundDepth = NULL,
                           SEXP* pEnvironment = NULL)
{
   RCNTXT* pRContext = r::getGlobalContext();
   int currentDepth = 0;
   while (pRContext->callflag)
   {
      if (isPrintableContext(pRContext))
      {
         // if the caller asked us to find user code, don't stop unless the
         // context we're examining has a source file attached
         if (++currentDepth >= depth &&
             !(findUserCode && !hasSourceRefs(pRContext)))
         {
             break;
         }
      }
      pRContext = pRContext->nextcontext;
   }

   // indicate the depth at which we stopped and the environment we found at
   // that depth, if requested
   if (pFoundDepth)
   {
      *pFoundDepth = currentDepth;
   }
   if (pEnvironment)
   {
      *pEnvironment = currentDepth == 0 ? R_GlobalEnv : pRContext->cloenv;
   }
   return pRContext;
}

SEXP getEnvironment(const int depth)
{
   return depth == 0 ? R_GlobalEnv : getFunctionContext(depth)->cloenv;
}

// return whether the context stack contains a pure (interactive) browser
bool inBrowseContext()
{
   RCNTXT* pRContext = r::getGlobalContext();
   while (pRContext->callflag)
   {
      if ((pRContext->callflag & CTXT_BROWSER) &&
          !(pRContext->callflag & CTXT_FUNCTION))
      {
         return true;
      }
      pRContext = pRContext->nextcontext;
   }
   return false;
}

// Return whether the current context is being evaluated inside a hidden
// (debugger internal) function at the top level.
bool insideDebugHiddenFunction()
{
   RCNTXT* pRContext = r::getGlobalContext();
   while (pRContext->callflag)
   {
      if (pRContext->callflag & CTXT_FUNCTION)
      {
         // If we find a debugger internal function before any user function,
         // hide it from the user callstack.
         if (isDebugHiddenContext(pRContext))
            return true;

         // If we find a user function before we encounter a debugger internal
         // function, don't hide the user code it invokes.
         if (hasSourceRefs(pRContext))
             return false;
      }
      pRContext = pRContext->nextcontext;
   }
   return false;
}

Error functionNameFromContext(const RCNTXT* pContext,
                              std::string* pFunctionName)
{
   return r::exec::RFunction(".rs.functionNameFromCall", pContext->call)
                            .call(pFunctionName);
}

json::Array callFramesAsJson()
{
   RCNTXT* pRContext = r::getGlobalContext();
   RCNTXT* pSrcContext = pRContext;
   json::Array listFrames;
   int contextDepth = 0;
   Error error;

   while (pRContext->callflag)
   {
      // If this context is hidden from the debugger, we want to avoid
      // delivering source refs for the context that invoked it. Pick up
      // source refs from the next context in this case.
      if (isDebugHiddenContext(pRContext))
      {
          pSrcContext = pRContext->nextcontext;
      }
      else if (isPrintableContext(pRContext))
      {
         json::Object varFrame;
         std::string functionName;
         error = functionNameFromContext(pRContext, &functionName);
         if (error)
         {
            LOG_ERROR(error);
         }
         varFrame["context_depth"] = ++contextDepth;
         varFrame["function_name"] = functionName;

         // in the linked list of R contexts, the srcref associated with each
         // context points to the place from which the context was invoked.
         // however, for traditional debugging, we want the call frame to show
         // where control *left* the frame to go to the next frame. pSrcContext
         // keeps track of the previous invocation.
         std::string filename;
         error = getFileNameFromContext(pSrcContext, &filename);
         if (error)
            LOG_ERROR(error);
         varFrame["file_name"] = filename;
         sourceRefToJson(pSrcContext->srcref, &varFrame);
         pSrcContext = pRContext;

         // extract the first line of the function. the client can optionally
         // use this to compute the source location as an offset into the
         // function rather than as an absolute file position (useful when
         // we need to debug a copy of the function rather than the real deal).
         SEXP srcRef = sourceRefsOfContext(pSrcContext);
         if (srcRef && TYPEOF(srcRef) != NILSXP)
         {
            varFrame["function_line_number"] = INTEGER(srcRef)[0];
         }

         std::string argList;
         SEXP args = CDR(pRContext->call);
         switch (TYPEOF(args))
         {
            case LISTSXP:
               error = r::exec::RFunction(".rs.argumentListSummary", args)
                 .call(&argList);
              break;
            case LANGSXP:
               error = r::exec::RFunction(".rs.promiseDescription", args)
                 .call(&argList);
               break;
         }
         if (error)
         {
            LOG_ERROR(error);
         }
         varFrame["argument_list"] = error ? "" : argList;

         listFrames.push_back(varFrame);
      }
      pRContext = pRContext->nextcontext;
   }
   return listFrames;
}

json::Array environmentListAsJson(int depth)
{
    using namespace r::sexp;
    Protect rProtect;
    std::vector<Variable> vars;
    SEXP env = getEnvironment(depth);
    listEnvironment(env, false, &rProtect, &vars);

    // get object details and transform to json
    json::Array listJson;
    std::transform(vars.begin(),
                   vars.end(),
                   std::back_inserter(listJson),
                   boost::bind(varToJson, env, _1));
    return listJson;
}

Error listEnvironment(boost::shared_ptr<int> pContextDepth,
                      const json::JsonRpcRequest&,
                      json::JsonRpcResponse* pResponse)
{
   // return list
   pResponse->setResult(environmentListAsJson(*pContextDepth));
   return Success();
}

// given a function context, indicate whether the copy of the source code
// for the function is different than the source code on disk.
bool functionIsOutOfSync(const RCNTXT *pContext,
                         std::string *pFunctionCode)
{
   Error error;

   // start by extracting the source code from the call site
   error = r::exec::RFunction(".rs.sourceCodeFromFunction",
                              getOriginalFunctionCallObject(pContext))
         .call(pFunctionCode);
   if (error)
   {
      LOG_ERROR(error);
      return true;
   }

   // make sure the function has source references
   if (!hasSourceRefs(pContext))
   {
      return true;
   }

   return functionDiffersFromSource(
            sourceRefsOfContext(pContext), *pFunctionCode);
}

// create a JSON object that contains information about the current environment;
// used both to initialize the environment state on first load and to send
// information about the new environment on a context change
json::Value commonEnvironmentStateData(int depth)
{
   json::Object varJson;
   bool useProvidedSource = false;
   std::string functionCode;

   varJson["context_depth"] = depth;
   varJson["environment_list"] = environmentListAsJson(depth);
   varJson["call_frames"] = callFramesAsJson();

   // if we're in a debug context, add information about the function currently
   // being debugged
   if (depth > 0)
   {
      RCNTXT* pContext = getFunctionContext(depth);
      std::string functionName;
      Error error = functionNameFromContext(pContext, &functionName);
      if (error)
      {
         LOG_ERROR(error);
      }
      varJson["function_name"] = functionName;

      // see if the function to be debugged is out of sync with its saved
      // sources (if available).
      if ((pContext))
      {
         useProvidedSource =
               functionIsOutOfSync(pContext, &functionCode) &&
               functionCode != "NULL";
      }
   }
   else
   {
      varJson["function_name"] = "";
   }

   // always emit the code for the function, even if we don't think that the
   // client's going to need it. we only checked the saved copy of the function
   // above; the client may be aware of local/unsaved changes to the function,
   // in which case it will need to fall back on a server-provided copy.
   varJson["use_provided_source"] = useProvidedSource;
   varJson["function_code"] = functionCode;

   return varJson;
}

void enqueContextDepthChangedEvent(int depth)
{
   // emit an event to the client indicating the new call frame and the
   // current state of the environment
   ClientEvent event (client_events::kContextDepthChanged,
                      commonEnvironmentStateData(depth));
   module_context::enqueClientEvent(event);
}

void enqueBrowserLineChangedEvent(const SEXP srcref)
{
   json::Object varJson;
   sourceRefToJson(srcref, &varJson);
   ClientEvent event (client_events::kBrowserLineChanged, varJson);
   module_context::enqueClientEvent(event);
}

Error setContextDepth(boost::shared_ptr<int> pContextDepth,
                      const json::JsonRpcRequest& request,
                      json::JsonRpcResponse* pResponse)
{
   // get the requested depth
   int requestedDepth;
   Error error = json::readParam(request.params, 0, &requestedDepth);
   if (error)
      return error;

   // set state for the new depth
   *pContextDepth = requestedDepth;

   // populate the new state on the client
   enqueContextDepthChangedEvent(*pContextDepth);

   return Success();
}

void onDetectChanges(module_context::ChangeSource source)
{
   s_environmentMonitor.checkForChanges();
}

void onConsolePrompt(boost::shared_ptr<int> pContextDepth,
                     boost::shared_ptr<RCNTXT*> pCurrentContext)
{
   int depth = 0;
   SEXP environmentTop = NULL;
   RCNTXT* pRContext =
         getFunctionContext(TOP_FUNCTION, true, &depth, &environmentTop);

   if (environmentTop != s_environmentMonitor.getMonitoredEnvironment() ||
       depth != *pContextDepth ||
       pRContext != *pCurrentContext)
   {
      json::Object varJson;

      // if we appear to be switching into debug mode, make sure there's a
      // browser call somewhere on the stack. if there isn't, then we're
      // probably just waiting for user input inside a function (e.g. scan());
      // assume the user isn't interested in seeing the function's internals.
      if (*pContextDepth == 0 &&
          !inBrowseContext())
      {
         return;
      }

      // start monitoring the enviroment at the new depth
      s_environmentMonitor.setMonitoredEnvironment(environmentTop);
      *pContextDepth = depth;
      *pCurrentContext = pRContext;
      enqueContextDepthChangedEvent(depth);
   }
   // if we're debugging and stayed in the same frame, update the line number
   else if (depth > 0)
   {
      // we don't want to send linenumber updates if the current depth is inside
      // a debug-hidden function
      if (!insideDebugHiddenFunction())
      {
         enqueBrowserLineChangedEvent(r::getGlobalContext()->srcref);
      }
   }
}

} // anonymous namespace

json::Value environmentStateAsJson()
{
   int contextDepth = 0;
   getFunctionContext(TOP_FUNCTION, true, &contextDepth);
   return commonEnvironmentStateData(contextDepth);
}

Error initialize()
{
   boost::shared_ptr<int> pContextDepth =
         boost::make_shared<int>(0);
   boost::shared_ptr<RCNTXT*> pCurrentContext =
         boost::make_shared<RCNTXT*>(r::getGlobalContext());

   // begin monitoring the environment
   SEXP environmentTop = NULL;
   getFunctionContext(TOP_FUNCTION, true, pContextDepth.get(), &environmentTop);
   s_environmentMonitor.setMonitoredEnvironment(environmentTop);

   // subscribe to events
   using boost::bind;
   using namespace session::module_context;
   events().onDetectChanges.connect(bind(onDetectChanges, _1));
   events().onConsolePrompt.connect(bind(onConsolePrompt,
                                         pContextDepth,
                                         pCurrentContext));

   json::JsonRpcFunction listEnv =
         boost::bind(listEnvironment, pContextDepth, _1, _2);
   json::JsonRpcFunction setCtxDepth =
         boost::bind(setContextDepth, pContextDepth, _1, _2);

   // source R functions
   ExecBlock initBlock ;
   initBlock.addFunctions()
      (bind(registerRBrowseFileHandler, handleRBrowseEnv))
      (bind(registerRpcMethod, "list_environment", listEnv))
      (bind(registerRpcMethod, "set_context_depth", setCtxDepth))
      (bind(sourceModuleRFile, "SessionEnvironment.R"));

   return initBlock.execute();
}

} // namespace environment
} // namespace modules
} // namesapce session

<commit_msg>check for zero-length function names<commit_after>/*
 * SessionEnvironment.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "SessionEnvironment.hpp"
#include "EnvironmentMonitor.hpp"

#include <algorithm>

#include <core/Exec.hpp>

#define INTERNAL_R_FUNCTIONS
#include <r/RSexp.hpp>
#include <r/RExec.hpp>
#include <r/session/RSession.hpp>
#include <r/RInterface.hpp>
#include <session/SessionModuleContext.hpp>
#include <session/SessionSourceDatabase.hpp>
#include <boost/foreach.hpp>

#include "EnvironmentUtils.hpp"

#define TOP_FUNCTION 1

using namespace core ;

namespace session {
namespace modules {
namespace environment {

EnvironmentMonitor s_environmentMonitor;

namespace {

bool handleRBrowseEnv(const core::FilePath& filePath)
{
   if (filePath.filename() == "wsbrowser.html")
   {
      module_context::showContent("R objects", filePath);
      return true;
   }
   else
   {
      return false;
   }
}

SEXP getOriginalFunctionCallObject(const RCNTXT* pContext)
{
   SEXP callObject = pContext->callfun;
   // enabling tracing on a function turns it into an S4 object with an
   // 'original' slot that includes the function's original contents. use
   // this instead if it's set up. (consider: is it safe to assume that S4
   // objects here are always traced functions, or do we need to compare classes
   // to be safe?)
   if (Rf_isS4(callObject))
   {
      callObject = r::sexp::getAttrib(callObject, "original");
   }
   return callObject;
}

Error getFileNameFromContext(const RCNTXT* pContext,
                             std::string* pFileName)
{
   SEXP srcref = pContext->srcref;
   return r::exec::RFunction(".rs.sourceFileFromRef", srcref)
                 .call(pFileName);
}

SEXP sourceRefsOfContext(const RCNTXT* pContext)
{
   return r::sexp::getAttrib(getOriginalFunctionCallObject(pContext), "srcref");
}

bool hasSourceRefs(const RCNTXT* pContext)
{
   SEXP srcref = sourceRefsOfContext(pContext);
   return srcref != NULL && TYPEOF(srcref) != NILSXP;
}

bool isDebugHiddenContext(RCNTXT* pContext)
{
   SEXP hideFlag = r::sexp::getAttrib(pContext->callfun, "hideFromDebugger");
   return TYPEOF(hideFlag) != NILSXP && r::sexp::asLogical(hideFlag);
}

// given a context from the context stack, indicate whether it should be emitted
// to the callstack.
bool isPrintableContext(RCNTXT* pContext)
{
   if (pContext->callflag & CTXT_FUNCTION)
   {
      if (isDebugHiddenContext(pContext))
      {
         // hidden function
         return false;
      }
      // printable function
      return true;
   }
   // not a function at all
   return false;
}

// return the function context at the given depth
RCNTXT* getFunctionContext(const int depth,
                           bool findUserCode = false,
                           int* pFoundDepth = NULL,
                           SEXP* pEnvironment = NULL)
{
   RCNTXT* pRContext = r::getGlobalContext();
   int currentDepth = 0;
   while (pRContext->callflag)
   {
      if (isPrintableContext(pRContext))
      {
         // if the caller asked us to find user code, don't stop unless the
         // context we're examining has a source file attached
         if (++currentDepth >= depth &&
             !(findUserCode && !hasSourceRefs(pRContext)))
         {
             break;
         }
      }
      pRContext = pRContext->nextcontext;
   }

   // indicate the depth at which we stopped and the environment we found at
   // that depth, if requested
   if (pFoundDepth)
   {
      *pFoundDepth = currentDepth;
   }
   if (pEnvironment)
   {
      *pEnvironment = currentDepth == 0 ? R_GlobalEnv : pRContext->cloenv;
   }
   return pRContext;
}

SEXP getEnvironment(const int depth)
{
   return depth == 0 ? R_GlobalEnv : getFunctionContext(depth)->cloenv;
}

// return whether the context stack contains a pure (interactive) browser
bool inBrowseContext()
{
   RCNTXT* pRContext = r::getGlobalContext();
   while (pRContext->callflag)
   {
      if ((pRContext->callflag & CTXT_BROWSER) &&
          !(pRContext->callflag & CTXT_FUNCTION))
      {
         return true;
      }
      pRContext = pRContext->nextcontext;
   }
   return false;
}

// Return whether the current context is being evaluated inside a hidden
// (debugger internal) function at the top level.
bool insideDebugHiddenFunction()
{
   RCNTXT* pRContext = r::getGlobalContext();
   while (pRContext->callflag)
   {
      if (pRContext->callflag & CTXT_FUNCTION)
      {
         // If we find a debugger internal function before any user function,
         // hide it from the user callstack.
         if (isDebugHiddenContext(pRContext))
            return true;

         // If we find a user function before we encounter a debugger internal
         // function, don't hide the user code it invokes.
         if (hasSourceRefs(pRContext))
             return false;
      }
      pRContext = pRContext->nextcontext;
   }
   return false;
}

Error functionNameFromContext(const RCNTXT* pContext,
                              std::string* pFunctionName)
{
   SEXP functionName;
   r::sexp::Protect protect;
   Error error = r::exec::RFunction(".rs.functionNameFromCall", pContext->call)
                            .call(&functionName, &protect);
   if (!error && r::sexp::length(functionName) > 0)
   {
      return r::sexp::extract(functionName, pFunctionName);
   }
   else
   {
      pFunctionName->clear();
   }
   return error;
}

json::Array callFramesAsJson()
{
   RCNTXT* pRContext = r::getGlobalContext();
   RCNTXT* pSrcContext = pRContext;
   json::Array listFrames;
   int contextDepth = 0;
   Error error;

   while (pRContext->callflag)
   {
      // If this context is hidden from the debugger, we want to avoid
      // delivering source refs for the context that invoked it. Pick up
      // source refs from the next context in this case.
      if (isDebugHiddenContext(pRContext))
      {
          pSrcContext = pRContext->nextcontext;
      }
      else if (isPrintableContext(pRContext))
      {
         json::Object varFrame;
         std::string functionName;
         error = functionNameFromContext(pRContext, &functionName);
         if (error)
         {
            LOG_ERROR(error);
         }
         varFrame["context_depth"] = ++contextDepth;
         varFrame["function_name"] = functionName;

         // in the linked list of R contexts, the srcref associated with each
         // context points to the place from which the context was invoked.
         // however, for traditional debugging, we want the call frame to show
         // where control *left* the frame to go to the next frame. pSrcContext
         // keeps track of the previous invocation.
         std::string filename;
         error = getFileNameFromContext(pSrcContext, &filename);
         if (error)
            LOG_ERROR(error);
         varFrame["file_name"] = filename;
         sourceRefToJson(pSrcContext->srcref, &varFrame);
         pSrcContext = pRContext;

         // extract the first line of the function. the client can optionally
         // use this to compute the source location as an offset into the
         // function rather than as an absolute file position (useful when
         // we need to debug a copy of the function rather than the real deal).
         SEXP srcRef = sourceRefsOfContext(pSrcContext);
         if (srcRef && TYPEOF(srcRef) != NILSXP)
         {
            varFrame["function_line_number"] = INTEGER(srcRef)[0];
         }

         std::string argList;
         SEXP args = CDR(pRContext->call);
         switch (TYPEOF(args))
         {
            case LISTSXP:
               error = r::exec::RFunction(".rs.argumentListSummary", args)
                 .call(&argList);
              break;
            case LANGSXP:
               error = r::exec::RFunction(".rs.promiseDescription", args)
                 .call(&argList);
               break;
         }
         if (error)
         {
            LOG_ERROR(error);
         }
         varFrame["argument_list"] = error ? "" : argList;

         listFrames.push_back(varFrame);
      }
      pRContext = pRContext->nextcontext;
   }
   return listFrames;
}

json::Array environmentListAsJson(int depth)
{
    using namespace r::sexp;
    Protect rProtect;
    std::vector<Variable> vars;
    SEXP env = getEnvironment(depth);
    listEnvironment(env, false, &rProtect, &vars);

    // get object details and transform to json
    json::Array listJson;
    std::transform(vars.begin(),
                   vars.end(),
                   std::back_inserter(listJson),
                   boost::bind(varToJson, env, _1));
    return listJson;
}

Error listEnvironment(boost::shared_ptr<int> pContextDepth,
                      const json::JsonRpcRequest&,
                      json::JsonRpcResponse* pResponse)
{
   // return list
   pResponse->setResult(environmentListAsJson(*pContextDepth));
   return Success();
}

// given a function context, indicate whether the copy of the source code
// for the function is different than the source code on disk.
bool functionIsOutOfSync(const RCNTXT *pContext,
                         std::string *pFunctionCode)
{
   Error error;

   // start by extracting the source code from the call site
   error = r::exec::RFunction(".rs.sourceCodeFromFunction",
                              getOriginalFunctionCallObject(pContext))
         .call(pFunctionCode);
   if (error)
   {
      LOG_ERROR(error);
      return true;
   }

   // make sure the function has source references
   if (!hasSourceRefs(pContext))
   {
      return true;
   }

   return functionDiffersFromSource(
            sourceRefsOfContext(pContext), *pFunctionCode);
}

// create a JSON object that contains information about the current environment;
// used both to initialize the environment state on first load and to send
// information about the new environment on a context change
json::Value commonEnvironmentStateData(int depth)
{
   json::Object varJson;
   bool useProvidedSource = false;
   std::string functionCode;

   varJson["context_depth"] = depth;
   varJson["environment_list"] = environmentListAsJson(depth);
   varJson["call_frames"] = callFramesAsJson();

   // if we're in a debug context, add information about the function currently
   // being debugged
   if (depth > 0)
   {
      RCNTXT* pContext = getFunctionContext(depth);
      std::string functionName;
      Error error = functionNameFromContext(pContext, &functionName);
      if (error)
      {
         LOG_ERROR(error);
      }
      varJson["function_name"] = functionName;

      // see if the function to be debugged is out of sync with its saved
      // sources (if available).
      if ((pContext))
      {
         useProvidedSource =
               functionIsOutOfSync(pContext, &functionCode) &&
               functionCode != "NULL";
      }
   }
   else
   {
      varJson["function_name"] = "";
   }

   // always emit the code for the function, even if we don't think that the
   // client's going to need it. we only checked the saved copy of the function
   // above; the client may be aware of local/unsaved changes to the function,
   // in which case it will need to fall back on a server-provided copy.
   varJson["use_provided_source"] = useProvidedSource;
   varJson["function_code"] = functionCode;

   return varJson;
}

void enqueContextDepthChangedEvent(int depth)
{
   // emit an event to the client indicating the new call frame and the
   // current state of the environment
   ClientEvent event (client_events::kContextDepthChanged,
                      commonEnvironmentStateData(depth));
   module_context::enqueClientEvent(event);
}

void enqueBrowserLineChangedEvent(const SEXP srcref)
{
   json::Object varJson;
   sourceRefToJson(srcref, &varJson);
   ClientEvent event (client_events::kBrowserLineChanged, varJson);
   module_context::enqueClientEvent(event);
}

Error setContextDepth(boost::shared_ptr<int> pContextDepth,
                      const json::JsonRpcRequest& request,
                      json::JsonRpcResponse* pResponse)
{
   // get the requested depth
   int requestedDepth;
   Error error = json::readParam(request.params, 0, &requestedDepth);
   if (error)
      return error;

   // set state for the new depth
   *pContextDepth = requestedDepth;

   // populate the new state on the client
   enqueContextDepthChangedEvent(*pContextDepth);

   return Success();
}

void onDetectChanges(module_context::ChangeSource source)
{
   s_environmentMonitor.checkForChanges();
}

void onConsolePrompt(boost::shared_ptr<int> pContextDepth,
                     boost::shared_ptr<RCNTXT*> pCurrentContext)
{
   int depth = 0;
   SEXP environmentTop = NULL;
   RCNTXT* pRContext =
         getFunctionContext(TOP_FUNCTION, true, &depth, &environmentTop);

   if (environmentTop != s_environmentMonitor.getMonitoredEnvironment() ||
       depth != *pContextDepth ||
       pRContext != *pCurrentContext)
   {
      json::Object varJson;

      // if we appear to be switching into debug mode, make sure there's a
      // browser call somewhere on the stack. if there isn't, then we're
      // probably just waiting for user input inside a function (e.g. scan());
      // assume the user isn't interested in seeing the function's internals.
      if (*pContextDepth == 0 &&
          !inBrowseContext())
      {
         return;
      }

      // start monitoring the enviroment at the new depth
      s_environmentMonitor.setMonitoredEnvironment(environmentTop);
      *pContextDepth = depth;
      *pCurrentContext = pRContext;
      enqueContextDepthChangedEvent(depth);
   }
   // if we're debugging and stayed in the same frame, update the line number
   else if (depth > 0)
   {
      // we don't want to send linenumber updates if the current depth is inside
      // a debug-hidden function
      if (!insideDebugHiddenFunction())
      {
         enqueBrowserLineChangedEvent(r::getGlobalContext()->srcref);
      }
   }
}

} // anonymous namespace

json::Value environmentStateAsJson()
{
   int contextDepth = 0;
   getFunctionContext(TOP_FUNCTION, true, &contextDepth);
   return commonEnvironmentStateData(contextDepth);
}

Error initialize()
{
   boost::shared_ptr<int> pContextDepth =
         boost::make_shared<int>(0);
   boost::shared_ptr<RCNTXT*> pCurrentContext =
         boost::make_shared<RCNTXT*>(r::getGlobalContext());

   // begin monitoring the environment
   SEXP environmentTop = NULL;
   getFunctionContext(TOP_FUNCTION, true, pContextDepth.get(), &environmentTop);
   s_environmentMonitor.setMonitoredEnvironment(environmentTop);

   // subscribe to events
   using boost::bind;
   using namespace session::module_context;
   events().onDetectChanges.connect(bind(onDetectChanges, _1));
   events().onConsolePrompt.connect(bind(onConsolePrompt,
                                         pContextDepth,
                                         pCurrentContext));

   json::JsonRpcFunction listEnv =
         boost::bind(listEnvironment, pContextDepth, _1, _2);
   json::JsonRpcFunction setCtxDepth =
         boost::bind(setContextDepth, pContextDepth, _1, _2);

   // source R functions
   ExecBlock initBlock ;
   initBlock.addFunctions()
      (bind(registerRBrowseFileHandler, handleRBrowseEnv))
      (bind(registerRpcMethod, "list_environment", listEnv))
      (bind(registerRpcMethod, "set_context_depth", setCtxDepth))
      (bind(sourceModuleRFile, "SessionEnvironment.R"));

   return initBlock.execute();
}

} // namespace environment
} // namespace modules
} // namesapce session

<|endoftext|>


<commit_before>#include "ppasskeeper.h"
#include "sha512.h"
#include "ppasskeeper-dir.h"
#include "stdio.h"

//local definitions
enum State {undefined, unlocked, locked };

/*********************************************************************
 *                                                                   *
 *                          Local Functions                          *
 *                                                                   *
 *********************************************************************/
void sha512(char* hash, const void* data, unsigned int length)
{
	uint8_t	sha512[SHA512_HASH_SIZE];
	SHA512Context s;

	SHA512Init(&s);
	SHA512Update(&s, data, length);
	SHA512Final(&s,sha512);

	for(int i = 0 ; i< SHA512_HASH_SIZE; i++)
		snprintf(hash + i *2,SHA512_HASH_SIZE+7,"%02x",sha512[i]);
}

State& cState()
{
	static State state=undefined;
	return state;
}

ppk_error grantAccess(const char* pwd="")
{
	char hash_pwd[SHA512_HASH_SIZE*2+1];
	char hash_file[SHA512_HASH_SIZE*2+1];

	FILE* f=fopen((setting_dir()+"/lock").c_str(), "r");
	if(f!=NULL)
	{
		int ret=fread(hash_file, sizeof(char), sizeof(hash_file),f);
		fclose(f);

		if(ret<=0)
		{
			cState()=unlocked;
			return PPK_OK;
		}

		sha512(hash_pwd, pwd, strlen(pwd));

		if(strcmp(hash_pwd, hash_file)==0)
		{
			cState()=unlocked;
			return PPK_OK;
		}
		else
		{
			cState()=locked;
			return PPK_CANNOT_UNLOCK;
		}
	}
	else
	{
		cState()=unlocked;

		/*
		 * Here is the problem for people who wants this "security",
		 * you just have to delete the file and all the security is gone ...
		 */
		return PPK_NOT_LOCKED;
	}
}

bool isLocked()
{
	if(cState() == undefined)
		grantAccess();

	return cState()==locked;
}

//Public functions
extern "C"
{
	ppk_error ppk_set_password(const char* pwd)
	{
		if(!isLocked())
		{
			char hash_pwd[SHA512_HASH_SIZE*2+1];

			FILE* f=fopen((setting_dir()+"/lock").c_str(), "w");
			if(f!=NULL)
			{
				sha512(hash_pwd, pwd, strlen(pwd));
				fwrite(hash_pwd, sizeof(char), sizeof(hash_pwd),f);
				fclose(f);

				return PPK_OK;
			}
			else
				return PPK_FILE_CANNOT_BE_ACCESSED;
		}
		else
			return PPK_NOT_LOCKED;
	}

	ppk_boolean ppk_is_locked()
	{
		return isLocked()?PPK_TRUE:PPK_FALSE;
	}

	ppk_error ppk_unlock(const char* password)
	{
		return grantAccess(password);
	}

	const char* ppk_settings_directory()
	{
		static std::string settingDir=setting_dir();
		return settingDir.c_str();
	}

	#ifdef I18N
	#include <libintl.h>
	#endif
	const char *ppk_error_get_string(ppk_error error_code)
	{
		const char *msg = NULL;

		switch(error_code)
		{
			case PPK_OK:
				msg="Everything went fine";
				break;
			case PPK_UNKNOWN_ERROR:
				msg="Unknown error";
				break;
			case PPK_UNSUPPORTED_METHOD:
				msg="Unsupported method";
				break;
			case PPK_INVALID_ARGUMENTS:
				msg="Invalid arguments";
				break;
			case PPK_LOCKED_NO_ACCESS:
				msg="PPassKeeper is locked, access denied";
				break;
			case PPK_ALREADY_LOCKED:
				msg="PPassKeeper is already locked";
				break;
			case PPK_CANNOT_LOCK:
				msg="PPassKeeper could not be locked (check your permissions)";
				break;
			case PPK_CANNOT_UNLOCK:
				msg="PPassKeeper could not be unlocked (it is not locked)";
				break;
			case PPK_NOT_LOCKED:
				msg="PPassKeeper could not be unlocked (it is not locked)";
				break;
			case PPK_MODULE_UNAVAILABLE:
				msg="No such module is available";
				break;
			case PPK_CANNOT_SAVE_PARAM:
				msg="The parameter cannot be saved";
				break;
			case PPK_CANNOT_GET_PARAM:
				msg="The requested parameter could not be retrieved";
				break;
			case PPK_ENTRY_UNAVAILABLE:
				msg="The requested entry could not be retrieved";
				break;
			case PPK_UNKNOWN_ENTRY_TYPE:
				msg="The requested entry has un unknown type";
				break;
			case PPK_FILE_CANNOT_BE_ACCESSED:
				msg="A file cannot be accessed. Check your permissions";
				break;
			case PPK_INSUFFICIENT_MEMORY:
				msg="Insufficient memory";
				break;
			case PPK_CANNOT_OPEN_PASSWORD_MANAGER:
				msg="Cannot open the requested password manager";
				break;
			case PPK_USER_CANCELLED:
				msg="User pressed cancel";
				break;
			case PPK_INCOMPATIBLE_FLAGS:
				msg="The requested flags are incompatible with the chosen method";
				break;
		}

		#ifdef I18N
		return msg ? gettext(msg) : gettext("<Undefined error>");
		#else
		return msg?msg:"<Undefined error>";
		#endif
	}
}
<commit_msg>Utils: Add a missing error message<commit_after>#include "ppasskeeper.h"
#include "sha512.h"
#include "ppasskeeper-dir.h"
#include "stdio.h"

//local definitions
enum State {undefined, unlocked, locked };

/*********************************************************************
 *                                                                   *
 *                          Local Functions                          *
 *                                                                   *
 *********************************************************************/
void sha512(char* hash, const void* data, unsigned int length)
{
	uint8_t	sha512[SHA512_HASH_SIZE];
	SHA512Context s;

	SHA512Init(&s);
	SHA512Update(&s, data, length);
	SHA512Final(&s,sha512);

	for(int i = 0 ; i< SHA512_HASH_SIZE; i++)
		snprintf(hash + i *2,SHA512_HASH_SIZE+7,"%02x",sha512[i]);
}

State& cState()
{
	static State state=undefined;
	return state;
}

ppk_error grantAccess(const char* pwd="")
{
	char hash_pwd[SHA512_HASH_SIZE*2+1];
	char hash_file[SHA512_HASH_SIZE*2+1];

	FILE* f=fopen((setting_dir()+"/lock").c_str(), "r");
	if(f!=NULL)
	{
		int ret=fread(hash_file, sizeof(char), sizeof(hash_file),f);
		fclose(f);

		if(ret<=0)
		{
			cState()=unlocked;
			return PPK_OK;
		}

		sha512(hash_pwd, pwd, strlen(pwd));

		if(strcmp(hash_pwd, hash_file)==0)
		{
			cState()=unlocked;
			return PPK_OK;
		}
		else
		{
			cState()=locked;
			return PPK_CANNOT_UNLOCK;
		}
	}
	else
	{
		cState()=unlocked;

		/*
		 * Here is the problem for people who wants this "security",
		 * you just have to delete the file and all the security is gone ...
		 */
		return PPK_NOT_LOCKED;
	}
}

bool isLocked()
{
	if(cState() == undefined)
		grantAccess();

	return cState()==locked;
}

//Public functions
extern "C"
{
	ppk_error ppk_set_password(const char* pwd)
	{
		if(!isLocked())
		{
			char hash_pwd[SHA512_HASH_SIZE*2+1];

			FILE* f=fopen((setting_dir()+"/lock").c_str(), "w");
			if(f!=NULL)
			{
				sha512(hash_pwd, pwd, strlen(pwd));
				fwrite(hash_pwd, sizeof(char), sizeof(hash_pwd),f);
				fclose(f);

				return PPK_OK;
			}
			else
				return PPK_FILE_CANNOT_BE_ACCESSED;
		}
		else
			return PPK_NOT_LOCKED;
	}

	ppk_boolean ppk_is_locked()
	{
		return isLocked()?PPK_TRUE:PPK_FALSE;
	}

	ppk_error ppk_unlock(const char* password)
	{
		return grantAccess(password);
	}

	const char* ppk_settings_directory()
	{
		static std::string settingDir=setting_dir();
		return settingDir.c_str();
	}

	#ifdef I18N
	#include <libintl.h>
	#endif
	const char *ppk_error_get_string(ppk_error error_code)
	{
		const char *msg = NULL;

		switch(error_code)
		{
			case PPK_OK:
				msg="Everything went fine";
				break;
			case PPK_UNKNOWN_ERROR:
				msg="Unknown error";
				break;
			case PPK_UNSUPPORTED_METHOD:
				msg="Unsupported method";
				break;
			case PPK_INVALID_ARGUMENTS:
				msg="Invalid arguments";
				break;
			case PPK_LOCKED_NO_ACCESS:
				msg="PPassKeeper is locked, access denied";
				break;
			case PPK_ALREADY_LOCKED:
				msg="PPassKeeper is already locked";
				break;
			case PPK_CANNOT_LOCK:
				msg="PPassKeeper could not be locked (check your permissions)";
				break;
			case PPK_CANNOT_UNLOCK:
				msg="PPassKeeper could not be unlocked (it is not locked)";
				break;
			case PPK_NOT_LOCKED:
				msg="PPassKeeper could not be unlocked (it is not locked)";
				break;
			case PPK_MODULE_UNAVAILABLE:
				msg="No such module is available";
				break;
			case PPK_CANNOT_SAVE_PARAM:
				msg="The parameter cannot be saved";
				break;
			case PPK_CANNOT_GET_PARAM:
				msg="The requested parameter could not be retrieved";
				break;
			case PPK_CANNOT_REMOVE_PARAM:
				msg="The requested parameter could not be deleted";
				break;
			case PPK_ENTRY_UNAVAILABLE:
				msg="The requested entry could not be retrieved";
				break;
			case PPK_UNKNOWN_ENTRY_TYPE:
				msg="The requested entry has un unknown type";
				break;
			case PPK_FILE_CANNOT_BE_ACCESSED:
				msg="A file cannot be accessed. Check your permissions";
				break;
			case PPK_INSUFFICIENT_MEMORY:
				msg="Insufficient memory";
				break;
			case PPK_CANNOT_OPEN_PASSWORD_MANAGER:
				msg="Cannot open the requested password manager";
				break;
			case PPK_USER_CANCELLED:
				msg="User pressed cancel";
				break;
			case PPK_INCOMPATIBLE_FLAGS:
				msg="The requested flags are incompatible with the chosen method";
				break;
		}

		#ifdef I18N
		return msg ? gettext(msg) : gettext("<Undefined error>");
		#else
		return msg?msg:"<Undefined error>";
		#endif
	}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: java_lang_object.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:54:03 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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.
 *
 *  This library 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 for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <jni.h>
#ifdef OS2
#include <typedefs.h>
#endif

#ifndef _SJ_JAVA_LANG_OBJECT_HXX
#define _SJ_JAVA_LANG_OBJECT_HXX

#include <tools/string.hxx>

#ifdef HAVE_64BIT_POINTERS
#error "no 64 bit pointer"
#else
#ifdef OS2
#define INT64_TO_PVOID(x) (void *)x.lo
inline jlong Make_Os2_Int64( INT32 hi, INT32 lo ) {jlong x = CONST64( hi, lo ); return x; }
#define PVOID_TO_INT64(x) Make_Os2_Int64( 0, (INT32)x )
#else //OS2
#define PVOID_TO_INT64(x) (jlong)(INT32)x
#define INT64_TO_PVOID(x) (void *)x
#endif //Os2
#endif

//=====================================================================
class java_lang_Class;
class  java_lang_Object
{
    // Zuweisungsoperator und Copy Konstruktor sind verboten
    java_lang_Object& operator = (java_lang_Object&) { return *this;};
    java_lang_Object(java_lang_Object&) {};

    static jclass getMyClass();
    // nur zum Zerstoeren des C++ Pointers in vom JSbxObject
    // abgeleiteten Java Objekten
    //static jclass getJSbxObjectClass();

protected:
    // der JAVA Handle zu dieser Klasse
    jobject object;
    // Klassendefinition

    // neu in SJ2:
    static jclass theClass;             // die Klasse braucht nur einmal angefordert werden !
    static jclass theJSbxObjectClass;   // die Klasse braucht nur einmal angefordert werden !
    static ULONG nObjCount;             // Zaehler fuer die Anzahl der Instanzen

public:
    // der Konstruktor, der fuer die abgeleiteten Klassen verwendet
    // werden soll.
    java_lang_Object( JNIEnv * pEnv, jobject myObj );
    // der eigentliche Konstruktor
    java_lang_Object();

    virtual ~java_lang_Object();

    void                saveRef( JNIEnv * pEnv, jobject myObj );
    jobject             getJavaObject() const { return object; }
    java_lang_Object *  GetWrapper() { return this; }

    java_lang_Class * getClass();

};

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.1.1.1.164); FILE MERGED 2005/09/05 12:56:12 rt 1.1.1.1.164.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: java_lang_object.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 20:13:09 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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.
 *
 *    This library 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 for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <jni.h>
#ifdef OS2
#include <typedefs.h>
#endif

#ifndef _SJ_JAVA_LANG_OBJECT_HXX
#define _SJ_JAVA_LANG_OBJECT_HXX

#include <tools/string.hxx>

#ifdef HAVE_64BIT_POINTERS
#error "no 64 bit pointer"
#else
#ifdef OS2
#define INT64_TO_PVOID(x) (void *)x.lo
inline jlong Make_Os2_Int64( INT32 hi, INT32 lo ) {jlong x = CONST64( hi, lo ); return x; }
#define PVOID_TO_INT64(x) Make_Os2_Int64( 0, (INT32)x )
#else //OS2
#define PVOID_TO_INT64(x) (jlong)(INT32)x
#define INT64_TO_PVOID(x) (void *)x
#endif //Os2
#endif

//=====================================================================
class java_lang_Class;
class  java_lang_Object
{
    // Zuweisungsoperator und Copy Konstruktor sind verboten
    java_lang_Object& operator = (java_lang_Object&) { return *this;};
    java_lang_Object(java_lang_Object&) {};

    static jclass getMyClass();
    // nur zum Zerstoeren des C++ Pointers in vom JSbxObject
    // abgeleiteten Java Objekten
    //static jclass getJSbxObjectClass();

protected:
    // der JAVA Handle zu dieser Klasse
    jobject object;
    // Klassendefinition

    // neu in SJ2:
    static jclass theClass;             // die Klasse braucht nur einmal angefordert werden !
    static jclass theJSbxObjectClass;   // die Klasse braucht nur einmal angefordert werden !
    static ULONG nObjCount;             // Zaehler fuer die Anzahl der Instanzen

public:
    // der Konstruktor, der fuer die abgeleiteten Klassen verwendet
    // werden soll.
    java_lang_Object( JNIEnv * pEnv, jobject myObj );
    // der eigentliche Konstruktor
    java_lang_Object();

    virtual ~java_lang_Object();

    void                saveRef( JNIEnv * pEnv, jobject myObj );
    jobject             getJavaObject() const { return object; }
    java_lang_Object *  GetWrapper() { return this; }

    java_lang_Class * getClass();

};

#endif
<|endoftext|>


<commit_before>#ifndef UTILS_H_INCLUDED
#define UTILS_H_INCLUDED

#include <cassert>

class Noncopyable
{
protected:
    Noncopyable() {}

private:
    Noncopyable(const Noncopyable&);
    void operator=(const Noncopyable&);
};

#ifndef NULL
#define NULL 0
#endif

#define THROW_C_ERROR()

#endif

<commit_msg>Add UniqueArray class<commit_after>#ifndef UTILS_H_INCLUDED
#define UTILS_H_INCLUDED

#include <cassert>

class Noncopyable
{
protected:
    Noncopyable() {}

private:
    Noncopyable(const Noncopyable&);
    void operator=(const Noncopyable&);
};

template<class T>
class UniqueArray
{
public:
    explicit UniqueArray(unsigned long size):
        data(new T[size])
    {}

    ~UniqueArray()
    { delete[] data; }

    T& operator[](unsigned long at)
    { return data[at]; }

public:
    T* const data;
};

#ifndef NULL
#define NULL 0
#endif

#define THROW_C_ERROR()

#endif

<|endoftext|>


<commit_before>/*
  Copyright (c) 2014 DataStax

  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 "uuids.hpp"

#include "cassandra.h"
#include "get_time.hpp"
#include "md5.hpp"
#include "scoped_mutex.hpp"

#include "third_party/boost/boost/random/mersenne_twister.hpp"
#include "third_party/boost/boost/random/random_device.hpp"

#include <stdio.h>

extern "C" {

void cass_uuid_generate_time(CassUuid output) {
  cass::Uuids::generate_v1(output);
}

void cass_uuid_from_time(cass_uint64_t time, CassUuid output) {
  cass::Uuids::generate_v1(time, output);
}

void cass_uuid_min_from_time(cass_uint64_t time, CassUuid output) {
  cass::Uuids::min_v1(time, output);
}

void cass_uuid_max_from_time(cass_uint64_t time, CassUuid output) {
  cass::Uuids::max_v1(time, output);
}

cass_uint64_t cass_uuid_timestamp(CassUuid uuid) {
  return cass::Uuids::get_unix_timestamp(uuid);
}

void cass_uuid_generate_random(CassUuid output) {
  cass::Uuids::generate_v4(output);
}

cass_uint8_t cass_uuid_version(CassUuid uuid) {
  return cass::Uuids::get_version(uuid);
}

void cass_uuid_string(CassUuid uuid, char* output) {
  cass::Uuids::to_string(uuid, output);
}

} // extern "C"

namespace {

  boost::random_device rd;
  boost::mt19937_64 ng_(rd());

class UuidsInitializer {
public:
  UuidsInitializer() { cass::Uuids::initialize_(); }
};

UuidsInitializer uuids_intitalizer_;

}

namespace cass {

uv_mutex_t Uuids::mutex_;
boost::atomic<uint64_t> Uuids::last_timestamp_;
uint64_t Uuids::CLOCK_SEQ_AND_NODE;

void Uuids::initialize_() {
  uv_mutex_init(&mutex_);
  last_timestamp_ = 0L;
  CLOCK_SEQ_AND_NODE = make_clock_seq_and_node();
}

void Uuids::generate_v1(Uuid uuid) {
  generate_v1(uuid_timestamp(), uuid);
}

void Uuids::generate_v1(uint64_t timestamp, Uuid uuid) {
  copy_timestamp(timestamp, 1, uuid);
  copy_clock_seq_and_node(CLOCK_SEQ_AND_NODE, uuid);
}

void Uuids::generate_v4(Uuid uuid) {
  ScopedMutex lock(&mutex_);
  uint64_t msb = ng_();
  uint64_t lsb = ng_();
  lock.unlock();

  copy_timestamp(msb, 4, uuid);
  lsb = (lsb & 0x3FFFFFFFFFFFFFFFLL) | 0x8000000000000000LL; // RFC4122 variant
  copy_clock_seq_and_node(lsb, uuid);
}

void Uuids::min_v1(uint64_t timestamp, Uuid uuid) {
  copy_timestamp(from_unix_timestamp(timestamp), 1, uuid);
  copy_clock_seq_and_node(MIN_CLOCK_SEQ_AND_NODE, uuid);
}

void Uuids::max_v1(uint64_t timestamp, Uuid uuid) {
  copy_timestamp(from_unix_timestamp(timestamp + 1) - 1, 1, uuid);
  copy_clock_seq_and_node(MAX_CLOCK_SEQ_AND_NODE, uuid);
}

uint64_t Uuids::get_unix_timestamp(Uuid uuid) {
  uint64_t timestamp = 0;

  if (get_version(uuid) != 1) {
    return 0;
  }

  timestamp |= static_cast<uint64_t>(uuid[3]);
  timestamp |= static_cast<uint64_t>(uuid[2]) << 8;
  timestamp |= static_cast<uint64_t>(uuid[1]) << 16;
  timestamp |= static_cast<uint64_t>(uuid[0]) << 24;

  timestamp |= static_cast<uint64_t>(uuid[5]) << 32;
  timestamp |= static_cast<uint64_t>(uuid[4]) << 40;

  timestamp |= static_cast<uint64_t>(uuid[7]) << 48;
  timestamp |= static_cast<uint64_t>(uuid[6]) << 56;

  timestamp &= 0x0FFFFFFFFFFFFFFFLL; // Clear version

  return to_milliseconds(timestamp - TIME_OFFSET_BETWEEN_UTC_AND_EPOCH);
}

void Uuids::to_string(Uuid uuid, char* output) {
  size_t pos = 0;
  for (int i = 0; i < 16; ++i) {
    char buf[3] = { '\0' };
    sprintf(buf, "%02x", uuid[i]);
    if (i == 4 || i == 6 || i == 8 || i == 10) {
      output[pos++] = '-';
    }
    output[pos++] = buf[0];
    output[pos++] = buf[1];
  }
  output[pos] = '\0';
}

void Uuids::copy_timestamp(uint64_t timestamp, uint8_t version, Uuid uuid) {
  uuid[3] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[2] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[1] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[0] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;

  uuid[5] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[4] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;

  uuid[7] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[6] = (timestamp & 0x000000000000000FL) | (version << 4);
}

uint64_t Uuids::uuid_timestamp() {
  while (true) {
    uint64_t now = from_unix_timestamp(get_time_since_epoch_ms());
    uint64_t last = last_timestamp_.load();
    if (now > last) {
      if (last_timestamp_.compare_exchange_strong(last, now)) {
        return now;
      }
    } else {
      uint64_t last_ms = to_milliseconds(last);
      if (to_milliseconds(now) < last_ms) {
        return last_timestamp_.fetch_add(1L);
      }
      uint64_t candidate = last + 1;
      if (to_milliseconds(candidate) == last_ms &&
          last_timestamp_.compare_exchange_strong(last, candidate)) {
        return candidate;
      }
    }
  }
}

uint64_t Uuids::make_clock_seq_and_node() {
  int count = 0;
  Md5 md5;

  uv_interface_address_t* addresses;
  int address_count;
  if (uv_interface_addresses(&addresses, &address_count).code == 0) {
    for (int i = 0; i < address_count; ++i) {
      char buf[256];
      uv_interface_address_t address = addresses[i];
      md5.update(address.name, strlen(address.name));
      if (address.address.address4.sin_family == AF_INET) {
        uv_ip4_name(&address.address.address4, buf, sizeof(buf));
        md5.update(buf, strlen(buf));
        count++;
      } else if (address.address.address4.sin_family == AF_INET6) {
        uv_ip6_name(&address.address.address6, buf, sizeof(buf));
        md5.update(buf, strlen(buf));
        count++;
      }
    }
    uv_free_interface_addresses(addresses, address_count);
  }

  assert(count > 0 && "No unique information for UUID node portion");

  uv_cpu_info_t* cpu_infos;
  int cpu_count;
  if (uv_cpu_info(&cpu_infos, &cpu_count).code == 0) {
    for (int i = 0; i < cpu_count; ++i) {
      uv_cpu_info_t cpu_info = cpu_infos[i];
      md5.update(cpu_info.model, strlen(cpu_info.model));
    }
    uv_free_cpu_info(cpu_infos, cpu_count);
  }

  uint8_t hash[16];
  md5.final(hash);

  uint64_t node = 0L;
  for (int i = 0; i < 6; ++i) {
    node |= (0x00000000000000FFLL & (long)hash[i]) << (i * 8);
  }
  node |= 0x0000010000000000LL; // Multicast bit

  uint64_t clock = ng_();
  uint64_t clock_seq_and_node = 0;
  clock_seq_and_node |= (clock & 0x0000000000003FFFLL) << 48;
  clock_seq_and_node |= 0x8000000000000000LL; // RFC4122 variant
  clock_seq_and_node |= node;

  return clock_seq_and_node;
}

} // namespace cass
<commit_msg>Slight rename in UUIDs<commit_after>/*
  Copyright (c) 2014 DataStax

  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 "uuids.hpp"

#include "cassandra.h"
#include "get_time.hpp"
#include "md5.hpp"
#include "scoped_mutex.hpp"

#include "third_party/boost/boost/random/mersenne_twister.hpp"
#include "third_party/boost/boost/random/random_device.hpp"

#include <stdio.h>

extern "C" {

void cass_uuid_generate_time(CassUuid output) {
  cass::Uuids::generate_v1(output);
}

void cass_uuid_from_time(cass_uint64_t time, CassUuid output) {
  cass::Uuids::generate_v1(time, output);
}

void cass_uuid_min_from_time(cass_uint64_t time, CassUuid output) {
  cass::Uuids::min_v1(time, output);
}

void cass_uuid_max_from_time(cass_uint64_t time, CassUuid output) {
  cass::Uuids::max_v1(time, output);
}

cass_uint64_t cass_uuid_timestamp(CassUuid uuid) {
  return cass::Uuids::get_unix_timestamp(uuid);
}

void cass_uuid_generate_random(CassUuid output) {
  cass::Uuids::generate_v4(output);
}

cass_uint8_t cass_uuid_version(CassUuid uuid) {
  return cass::Uuids::get_version(uuid);
}

void cass_uuid_string(CassUuid uuid, char* output) {
  cass::Uuids::to_string(uuid, output);
}

} // extern "C"

namespace {

boost::random_device rd;
boost::mt19937_64 ng(rd());

class UuidsInitializer {
public:
  UuidsInitializer() { cass::Uuids::initialize_(); }
};

UuidsInitializer uuids_intitalizer_;

}

namespace cass {

uv_mutex_t Uuids::mutex_;
boost::atomic<uint64_t> Uuids::last_timestamp_;
uint64_t Uuids::CLOCK_SEQ_AND_NODE;

void Uuids::initialize_() {
  uv_mutex_init(&mutex_);
  last_timestamp_ = 0L;
  CLOCK_SEQ_AND_NODE = make_clock_seq_and_node();
}

void Uuids::generate_v1(Uuid uuid) {
  generate_v1(uuid_timestamp(), uuid);
}

void Uuids::generate_v1(uint64_t timestamp, Uuid uuid) {
  copy_timestamp(timestamp, 1, uuid);
  copy_clock_seq_and_node(CLOCK_SEQ_AND_NODE, uuid);
}

void Uuids::generate_v4(Uuid uuid) {
  ScopedMutex lock(&mutex_);
  uint64_t msb = ng();
  uint64_t lsb = ng();
  lock.unlock();

  copy_timestamp(msb, 4, uuid);
  lsb = (lsb & 0x3FFFFFFFFFFFFFFFLL) | 0x8000000000000000LL; // RFC4122 variant
  copy_clock_seq_and_node(lsb, uuid);
}

void Uuids::min_v1(uint64_t timestamp, Uuid uuid) {
  copy_timestamp(from_unix_timestamp(timestamp), 1, uuid);
  copy_clock_seq_and_node(MIN_CLOCK_SEQ_AND_NODE, uuid);
}

void Uuids::max_v1(uint64_t timestamp, Uuid uuid) {
  copy_timestamp(from_unix_timestamp(timestamp + 1) - 1, 1, uuid);
  copy_clock_seq_and_node(MAX_CLOCK_SEQ_AND_NODE, uuid);
}

uint64_t Uuids::get_unix_timestamp(Uuid uuid) {
  uint64_t timestamp = 0;

  if (get_version(uuid) != 1) {
    return 0;
  }

  timestamp |= static_cast<uint64_t>(uuid[3]);
  timestamp |= static_cast<uint64_t>(uuid[2]) << 8;
  timestamp |= static_cast<uint64_t>(uuid[1]) << 16;
  timestamp |= static_cast<uint64_t>(uuid[0]) << 24;

  timestamp |= static_cast<uint64_t>(uuid[5]) << 32;
  timestamp |= static_cast<uint64_t>(uuid[4]) << 40;

  timestamp |= static_cast<uint64_t>(uuid[7]) << 48;
  timestamp |= static_cast<uint64_t>(uuid[6]) << 56;

  timestamp &= 0x0FFFFFFFFFFFFFFFLL; // Clear version

  return to_milliseconds(timestamp - TIME_OFFSET_BETWEEN_UTC_AND_EPOCH);
}

void Uuids::to_string(Uuid uuid, char* output) {
  size_t pos = 0;
  for (int i = 0; i < 16; ++i) {
    char buf[3] = { '\0' };
    sprintf(buf, "%02x", uuid[i]);
    if (i == 4 || i == 6 || i == 8 || i == 10) {
      output[pos++] = '-';
    }
    output[pos++] = buf[0];
    output[pos++] = buf[1];
  }
  output[pos] = '\0';
}

void Uuids::copy_timestamp(uint64_t timestamp, uint8_t version, Uuid uuid) {
  uuid[3] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[2] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[1] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[0] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;

  uuid[5] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[4] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;

  uuid[7] = timestamp & 0x00000000000000FFL;
  timestamp >>= 8;
  uuid[6] = (timestamp & 0x000000000000000FL) | (version << 4);
}

uint64_t Uuids::uuid_timestamp() {
  while (true) {
    uint64_t now = from_unix_timestamp(get_time_since_epoch_ms());
    uint64_t last = last_timestamp_.load();
    if (now > last) {
      if (last_timestamp_.compare_exchange_strong(last, now)) {
        return now;
      }
    } else {
      uint64_t last_ms = to_milliseconds(last);
      if (to_milliseconds(now) < last_ms) {
        return last_timestamp_.fetch_add(1L);
      }
      uint64_t candidate = last + 1;
      if (to_milliseconds(candidate) == last_ms &&
          last_timestamp_.compare_exchange_strong(last, candidate)) {
        return candidate;
      }
    }
  }
}

uint64_t Uuids::make_clock_seq_and_node() {
  int count = 0;
  Md5 md5;

  uv_interface_address_t* addresses;
  int address_count;
  if (uv_interface_addresses(&addresses, &address_count).code == 0) {
    for (int i = 0; i < address_count; ++i) {
      char buf[256];
      uv_interface_address_t address = addresses[i];
      md5.update(address.name, strlen(address.name));
      if (address.address.address4.sin_family == AF_INET) {
        uv_ip4_name(&address.address.address4, buf, sizeof(buf));
        md5.update(buf, strlen(buf));
        count++;
      } else if (address.address.address4.sin_family == AF_INET6) {
        uv_ip6_name(&address.address.address6, buf, sizeof(buf));
        md5.update(buf, strlen(buf));
        count++;
      }
    }
    uv_free_interface_addresses(addresses, address_count);
  }

  assert(count > 0 && "No unique information for UUID node portion");

  uv_cpu_info_t* cpu_infos;
  int cpu_count;
  if (uv_cpu_info(&cpu_infos, &cpu_count).code == 0) {
    for (int i = 0; i < cpu_count; ++i) {
      uv_cpu_info_t cpu_info = cpu_infos[i];
      md5.update(cpu_info.model, strlen(cpu_info.model));
    }
    uv_free_cpu_info(cpu_infos, cpu_count);
  }

  uint8_t hash[16];
  md5.final(hash);

  uint64_t node = 0L;
  for (int i = 0; i < 6; ++i) {
    node |= (0x00000000000000FFLL & (long)hash[i]) << (i * 8);
  }
  node |= 0x0000010000000000LL; // Multicast bit

  uint64_t clock = ng();
  uint64_t clock_seq_and_node = 0;
  clock_seq_and_node |= (clock & 0x0000000000003FFFLL) << 48;
  clock_seq_and_node |= 0x8000000000000000LL; // RFC4122 variant
  clock_seq_and_node |= node;

  return clock_seq_and_node;
}

} // namespace cass
<|endoftext|>


<commit_before>/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2013 Nest Labs, 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 <support/Pool.h>

namespace chip {

StaticAllocatorBitmap::StaticAllocatorBitmap(void * storage, std::atomic<tBitChunkType> * usage, size_t capacity,
                                             size_t elementSize) :
    StaticAllocatorBase(capacity),
    mElements(storage), mElementSize(elementSize), mUsage(usage)
{
    for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
    {
        mUsage[word].store(0);
    }
}

void * StaticAllocatorBitmap::Allocate()
{
    for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
    {
        auto & usage = mUsage[word];
        auto value   = usage.load(std::memory_order_relaxed);
        for (size_t offset = 0; offset < kBitChunkSize && offset + word * kBitChunkSize < Capacity(); ++offset)
        {
            if ((value & (kBit1 << offset)) == 0)
            {
                if (usage.compare_exchange_strong(value, value | (kBit1 << offset)))
                {
                    mAllocated++;
                    return At(word * kBitChunkSize + offset);
                }
                else
                {
                    value = usage.load(std::memory_order_relaxed); // if there is a race, update new usage
                }
            }
        }
    }
    return nullptr;
}

void StaticAllocatorBitmap::Deallocate(void * element)
{
    size_t index  = IndexOf(element);
    size_t word   = index / kBitChunkSize;
    size_t offset = index - (word * kBitChunkSize);

    // ensure the element is in the pool
    assert(index < Capacity());

    auto value = mUsage[word].fetch_and(~(kBit1 << offset));
    assert((value & (kBit1 << offset)) != 0); // assert fail when free an unused slot
    mAllocated--;
}

} // namespace chip
<commit_msg>Fix warnings -Wunused-variable in release (#4418)<commit_after>/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2013 Nest Labs, 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 <support/Pool.h>

#include <nlassert.h>

namespace chip {

StaticAllocatorBitmap::StaticAllocatorBitmap(void * storage, std::atomic<tBitChunkType> * usage, size_t capacity,
                                             size_t elementSize) :
    StaticAllocatorBase(capacity),
    mElements(storage), mElementSize(elementSize), mUsage(usage)
{
    for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
    {
        mUsage[word].store(0);
    }
}

void * StaticAllocatorBitmap::Allocate()
{
    for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
    {
        auto & usage = mUsage[word];
        auto value   = usage.load(std::memory_order_relaxed);
        for (size_t offset = 0; offset < kBitChunkSize && offset + word * kBitChunkSize < Capacity(); ++offset)
        {
            if ((value & (kBit1 << offset)) == 0)
            {
                if (usage.compare_exchange_strong(value, value | (kBit1 << offset)))
                {
                    mAllocated++;
                    return At(word * kBitChunkSize + offset);
                }
                else
                {
                    value = usage.load(std::memory_order_relaxed); // if there is a race, update new usage
                }
            }
        }
    }
    return nullptr;
}

void StaticAllocatorBitmap::Deallocate(void * element)
{
    size_t index  = IndexOf(element);
    size_t word   = index / kBitChunkSize;
    size_t offset = index - (word * kBitChunkSize);

    // ensure the element is in the pool
    assert(index < Capacity());

    auto value = mUsage[word].fetch_and(~(kBit1 << offset));
    nlASSERT((value & (kBit1 << offset)) != 0); // assert fail when free an unused slot
    mAllocated--;
}

} // namespace chip
<|endoftext|>


<commit_before>#include "value.hpp"
#include "classes.hpp"
#include "document.hpp"
#include "tree/tree.hpp"
#include "runtime.hpp"
#include "collector-common.hpp"

namespace Mirb
{
	struct VerifyFunc
	{
		void operator()(const ValueStorage &storage)
		{
			storage.array->assert_valid_light();
		}

		void operator()(const CharArray &string)
		{
			char_t *data = Accesser::CharArray::data(string);

			if(data && !Accesser::CharArray::static_data(string))
				(&VariableBlock::from_memory((const void *)data))->assert_valid_light();
		}

		template<class T> void operator()(T *value)
		{
			value->assert_valid_light();
		}
	};

	template<Type::Enum type> struct VerifyClass
	{
		typedef void Result;
		typedef typename Type::ToClass<type>::Class Class;

		static void func(value_t value)
		{
			VerifyFunc func;

			if(!Value::immediate(type))
				static_cast<Class *>(value)->mark(func);
		}
	};

	void Value::assert_valid_extended()
	{
		if(prelude_unlikely(context->bootstrap))
			return;

		Type::action<VerifyClass>(type(), this);
	}

	Type::Enum Value::type_table[literal_count];

	bool Value::is_fixnum(value_t value)
	{
		return (size_t)value & fixnum_mask;
	}

	void Value::initialize_type_table()
	{
		for(size_t i = 0; i < literal_count; ++i)
		{
			if(i & fixnum_mask)
			{
				type_table[i] = Type::Fixnum;
				continue;
			}

			switch(i)
			{
				case value_nil_num:
				{
					type_table[i] = Type::Nil;
					break;
				}

				case value_false_num:
				{
					type_table[i] = Type::False;
					break;
				}

				case value_true_num:
				{
					type_table[i] = Type::True;
					break;
				}

				default:
				{
					type_table[i] = Type::None;
					break;
				}
			}
		}
	}

	void Value::initialize_class_table()
	{
		for(size_t i = 0; i < literal_count; ++i)
		{
			if(i & fixnum_mask)
			{
				context->class_of_table[i] = Mirb::context->fixnum_class;
				continue;
			}

			switch(i)
			{
				case value_nil_num:
				{
					context->class_of_table[i] = context->nil_class;
					break;
				}

				case value_false_num:
				{
					context->class_of_table[i] = context->false_class;
					break;
				}

				case value_true_num:
				{
					context->class_of_table[i] = context->true_class;
					break;
				}

				default:
				{
					context->class_of_table[i] = nullptr;
					break;
				}
			}
		}
	}

	bool Value::test()
	{
		return ((size_t)this & ~(value_nil_num | value_false_num)) != 0;
	}

	bool Value::object_ref()
	{
		return ((size_t)this & object_ref_mask) == 0;
	}

	Mirb::Class *Value::class_of_literal()
	{
		return context->class_of_table[(size_t)this & literal_mask];
	}

	Type::Enum Value::type()
	{
		if(object_ref())
			return value_type; // Do a simple cast here to avoid stack overflow when debugging is enabled
		else
			return type_table[(size_t)this & literal_mask];
	}

	const size_t Value::magic_value = 12345;

	#ifdef DEBUG
		const Value::data_field Value::mark_list = &Value::mark_data;
		const Value::data_field Value::thread_list = &Value::thread_data;
		value_t * const Value::list_end = (value_t *)0xF0;
	#else
		const Value::data_field Value::mark_list = &Value::data;
		const Value::data_field Value::thread_list = &Value::data;
		value_t * const Value::list_end = nullptr;
	#endif

	void Value::setup()
	{
		marked = false;

		#ifdef DEBUG
			alive = true;
			magic = magic_value;
			refs = nullptr;
			mark_data = list_end;
			thread_data = list_end;
		#else
			data = list_end;
		#endif

		#ifdef VALGRIND
			Collector::heap_list.append(this);
		#endif
	}

	void Value::assert_valid_base()
	{
		mirb_debug(mirb_debug_assert(magic == magic_value));
		mirb_debug_assert(value_type != Type::None && value_type != Type::FreeBlock);
	}

		void Value::assert_alive()
	{
		assert_valid_base();

		mirb_debug(mirb_debug_assert(alive));
	}

	void assert_valid_extended();

	void Value::assert_valid_light()
	{
		if(object_ref())
		{
			assert_alive();
			mirb_debug_assert(marked == false);
			mirb_debug_assert((this->*mark_list) == Value::list_end);
			mirb_debug_assert((this->*thread_list) == Value::list_end);
		}
	}

	void Value::assert_valid()
	{
		#ifdef DEBUG
			assert_valid_light();

			#ifdef DEBUG_MEMORY
				if(object_ref())
					assert_valid_extended();
			#endif
		#endif
	}

	bool Value::kind_of(Class *klass)
	{
		return subclass_of(klass, internal_class_of(this));
	}

	Value::Value(const Value &other) : value_type(other.value_type), hashed(other.hashed), flag(other.flag), flag2(other.flag2)
	{
		setup();
	}

	Value::Value(Type::Enum type) : value_type(type), hashed(false), flag(false)
	{
		setup();
	}

	value_t Value::dup(value_t obj)
	{
		CharArray obj_value = inspect(class_of(obj));

		raise(context->type_error, "Unable to duplicate instances of " + obj_value);
	}

	template<Type::Enum type> struct HashValue
	{
		typedef size_t Result;
		typedef typename Type::ToClass<type>::Class Class;

		static size_t func(value_t value)
		{
			return static_cast<Class *>(value)->hash();
		}
	};

	size_t hash_value(value_t value)
	{
		value->assert_valid();

		return Type::action<HashValue>(value->type(), value);
	}
};
<commit_msg>Set flag2 to false on construction.<commit_after>#include "value.hpp"
#include "classes.hpp"
#include "document.hpp"
#include "tree/tree.hpp"
#include "runtime.hpp"
#include "collector-common.hpp"

namespace Mirb
{
	struct VerifyFunc
	{
		void operator()(const ValueStorage &storage)
		{
			storage.array->assert_valid_light();
		}

		void operator()(const CharArray &string)
		{
			char_t *data = Accesser::CharArray::data(string);

			if(data && !Accesser::CharArray::static_data(string))
				(&VariableBlock::from_memory((const void *)data))->assert_valid_light();
		}

		template<class T> void operator()(T *value)
		{
			value->assert_valid_light();
		}
	};

	template<Type::Enum type> struct VerifyClass
	{
		typedef void Result;
		typedef typename Type::ToClass<type>::Class Class;

		static void func(value_t value)
		{
			VerifyFunc func;

			if(!Value::immediate(type))
				static_cast<Class *>(value)->mark(func);
		}
	};

	void Value::assert_valid_extended()
	{
		if(prelude_unlikely(context->bootstrap))
			return;

		Type::action<VerifyClass>(type(), this);
	}

	Type::Enum Value::type_table[literal_count];

	bool Value::is_fixnum(value_t value)
	{
		return (size_t)value & fixnum_mask;
	}

	void Value::initialize_type_table()
	{
		for(size_t i = 0; i < literal_count; ++i)
		{
			if(i & fixnum_mask)
			{
				type_table[i] = Type::Fixnum;
				continue;
			}

			switch(i)
			{
				case value_nil_num:
				{
					type_table[i] = Type::Nil;
					break;
				}

				case value_false_num:
				{
					type_table[i] = Type::False;
					break;
				}

				case value_true_num:
				{
					type_table[i] = Type::True;
					break;
				}

				default:
				{
					type_table[i] = Type::None;
					break;
				}
			}
		}
	}

	void Value::initialize_class_table()
	{
		for(size_t i = 0; i < literal_count; ++i)
		{
			if(i & fixnum_mask)
			{
				context->class_of_table[i] = Mirb::context->fixnum_class;
				continue;
			}

			switch(i)
			{
				case value_nil_num:
				{
					context->class_of_table[i] = context->nil_class;
					break;
				}

				case value_false_num:
				{
					context->class_of_table[i] = context->false_class;
					break;
				}

				case value_true_num:
				{
					context->class_of_table[i] = context->true_class;
					break;
				}

				default:
				{
					context->class_of_table[i] = nullptr;
					break;
				}
			}
		}
	}

	bool Value::test()
	{
		return ((size_t)this & ~(value_nil_num | value_false_num)) != 0;
	}

	bool Value::object_ref()
	{
		return ((size_t)this & object_ref_mask) == 0;
	}

	Mirb::Class *Value::class_of_literal()
	{
		return context->class_of_table[(size_t)this & literal_mask];
	}

	Type::Enum Value::type()
	{
		if(object_ref())
			return value_type; // Do a simple cast here to avoid stack overflow when debugging is enabled
		else
			return type_table[(size_t)this & literal_mask];
	}

	const size_t Value::magic_value = 12345;

	#ifdef DEBUG
		const Value::data_field Value::mark_list = &Value::mark_data;
		const Value::data_field Value::thread_list = &Value::thread_data;
		value_t * const Value::list_end = (value_t *)0xF0;
	#else
		const Value::data_field Value::mark_list = &Value::data;
		const Value::data_field Value::thread_list = &Value::data;
		value_t * const Value::list_end = nullptr;
	#endif

	void Value::setup()
	{
		marked = false;

		#ifdef DEBUG
			alive = true;
			magic = magic_value;
			refs = nullptr;
			mark_data = list_end;
			thread_data = list_end;
		#else
			data = list_end;
		#endif

		#ifdef VALGRIND
			Collector::heap_list.append(this);
		#endif
	}

	void Value::assert_valid_base()
	{
		mirb_debug(mirb_debug_assert(magic == magic_value));
		mirb_debug_assert(value_type != Type::None && value_type != Type::FreeBlock);
	}

		void Value::assert_alive()
	{
		assert_valid_base();

		mirb_debug(mirb_debug_assert(alive));
	}

	void assert_valid_extended();

	void Value::assert_valid_light()
	{
		if(object_ref())
		{
			assert_alive();
			mirb_debug_assert(marked == false);
			mirb_debug_assert((this->*mark_list) == Value::list_end);
			mirb_debug_assert((this->*thread_list) == Value::list_end);
		}
	}

	void Value::assert_valid()
	{
		#ifdef DEBUG
			assert_valid_light();

			#ifdef DEBUG_MEMORY
				if(object_ref())
					assert_valid_extended();
			#endif
		#endif
	}

	bool Value::kind_of(Class *klass)
	{
		return subclass_of(klass, internal_class_of(this));
	}

	Value::Value(const Value &other) : value_type(other.value_type), hashed(other.hashed), flag(other.flag), flag2(other.flag2)
	{
		setup();
	}

	Value::Value(Type::Enum type) : value_type(type), hashed(false), flag(false), flag2(false)
	{
		setup();
	}

	value_t Value::dup(value_t obj)
	{
		CharArray obj_value = inspect(class_of(obj));

		raise(context->type_error, "Unable to duplicate instances of " + obj_value);
	}

	template<Type::Enum type> struct HashValue
	{
		typedef size_t Result;
		typedef typename Type::ToClass<type>::Class Class;

		static size_t func(value_t value)
		{
			return static_cast<Class *>(value)->hash();
		}
	};

	size_t hash_value(value_t value)
	{
		value->assert_valid();

		return Type::action<HashValue>(value->type(), value);
	}
};
<|endoftext|>


<commit_before>#include "attr-path.hh"
#include "eval-inline.hh"
#include "util.hh"

namespace nix {

static Strings parseAttrPath(const string & s)
{
    Strings res;
    string cur;
    string::const_iterator i = s.begin();
    while (i != s.end()) {
        if (*i == '.') {
            res.push_back(cur);
            cur.clear();
        } else if (*i == '"') {
            ++i;
            while (1) {
                if (i == s.end())
                    throw Error(format("missing closing quote in selection path '%1%'") % s);
                if (*i == '"') break;
                cur.push_back(*i++);
            }
        } else
            cur.push_back(*i);
        ++i;
    }
    if (!cur.empty()) res.push_back(cur);
    return res;
}

Value * findAlongAttrPath(EvalState & state, const string & attrPath,
    Bindings & autoArgs, Value & vIn)
{
    Strings tokens = parseAttrPath(attrPath);

    Error attrError =
        Error(format("attribute selection path '%1%' does not match expression") % attrPath);

    Value * v = &vIn;

    for (auto & attr : tokens) {

        /* Is i an index (integer) or a normal attribute name? */
        enum { apAttr, apIndex } apType = apAttr;
        unsigned int attrIndex;
        if (string2Int(attr, attrIndex)) apType = apIndex;

        /* Evaluate the expression. */
        Value * vNew = state.allocValue();
        state.autoCallFunction(autoArgs, *v, *vNew);
        v = vNew;
        state.forceValue(*v);

        /* It should evaluate to either a set or an expression,
           according to what is specified in the attrPath. */

        if (apType == apAttr) {

            if (v->type != tAttrs)
                throw TypeError(
                    format("the expression selected by the selection path '%1%' should be a set but is %2%")
                    % attrPath % showType(*v));

            if (attr.empty())
                throw Error(format("empty attribute name in selection path '%1%'") % attrPath);

            Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
            if (a == v->attrs->end())
                throw Error(format("attribute '%1%' in selection path '%2%' not found") % attr % attrPath);
            v = &*a->value;
        }

        else if (apType == apIndex) {

            if (!v->isList())
                throw TypeError(
                    format("the expression selected by the selection path '%1%' should be a list but is %2%")
                    % attrPath % showType(*v));

            if (attrIndex >= v->listSize())
                throw Error(format("list index %1% in selection path '%2%' is out of range") % attrIndex % attrPath);

            v = v->listElems()[attrIndex];
        }

    }

    return v;
}

Pos findDerivationFilename(EvalState & state, Value & v, std::string what)
{
    Value * v2;
    try {
        auto dummyArgs = state.allocBindings(0);
        v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v);
    } catch (Error &) {
        throw Error("package '%s' has no source location information", what);
    }

    // FIXME: is it possible to extract the Pos object instead of doing this
    //        toString + parsing?
    auto pos = state.forceString(*v2);

    auto colon = pos.rfind(':');
    if (colon == std::string::npos)
        throw Error("cannot parse meta.position attribute '%s'", pos);

    std::string filename(pos, 0, colon);
    unsigned int lineno;
    try {
        lineno = std::stoi(std::string(pos, colon + 1));
    } catch (std::invalid_argument & e) {
        throw Error("cannot parse line number '%s'", pos);
    }

    Symbol file = state.symbols.create(filename);

    return { file, lineno, 0 };
}

}
<commit_msg>libexpr: remove unused attrError<commit_after>#include "attr-path.hh"
#include "eval-inline.hh"
#include "util.hh"

namespace nix {

static Strings parseAttrPath(const string & s)
{
    Strings res;
    string cur;
    string::const_iterator i = s.begin();
    while (i != s.end()) {
        if (*i == '.') {
            res.push_back(cur);
            cur.clear();
        } else if (*i == '"') {
            ++i;
            while (1) {
                if (i == s.end())
                    throw Error(format("missing closing quote in selection path '%1%'") % s);
                if (*i == '"') break;
                cur.push_back(*i++);
            }
        } else
            cur.push_back(*i);
        ++i;
    }
    if (!cur.empty()) res.push_back(cur);
    return res;
}

Value * findAlongAttrPath(EvalState & state, const string & attrPath,
    Bindings & autoArgs, Value & vIn)
{
    Strings tokens = parseAttrPath(attrPath);

    Value * v = &vIn;

    for (auto & attr : tokens) {

        /* Is i an index (integer) or a normal attribute name? */
        enum { apAttr, apIndex } apType = apAttr;
        unsigned int attrIndex;
        if (string2Int(attr, attrIndex)) apType = apIndex;

        /* Evaluate the expression. */
        Value * vNew = state.allocValue();
        state.autoCallFunction(autoArgs, *v, *vNew);
        v = vNew;
        state.forceValue(*v);

        /* It should evaluate to either a set or an expression,
           according to what is specified in the attrPath. */

        if (apType == apAttr) {

            if (v->type != tAttrs)
                throw TypeError(
                    format("the expression selected by the selection path '%1%' should be a set but is %2%")
                    % attrPath % showType(*v));

            if (attr.empty())
                throw Error(format("empty attribute name in selection path '%1%'") % attrPath);

            Bindings::iterator a = v->attrs->find(state.symbols.create(attr));
            if (a == v->attrs->end())
                throw Error(format("attribute '%1%' in selection path '%2%' not found") % attr % attrPath);
            v = &*a->value;
        }

        else if (apType == apIndex) {

            if (!v->isList())
                throw TypeError(
                    format("the expression selected by the selection path '%1%' should be a list but is %2%")
                    % attrPath % showType(*v));

            if (attrIndex >= v->listSize())
                throw Error(format("list index %1% in selection path '%2%' is out of range") % attrIndex % attrPath);

            v = v->listElems()[attrIndex];
        }

    }

    return v;
}

Pos findDerivationFilename(EvalState & state, Value & v, std::string what)
{
    Value * v2;
    try {
        auto dummyArgs = state.allocBindings(0);
        v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v);
    } catch (Error &) {
        throw Error("package '%s' has no source location information", what);
    }

    // FIXME: is it possible to extract the Pos object instead of doing this
    //        toString + parsing?
    auto pos = state.forceString(*v2);

    auto colon = pos.rfind(':');
    if (colon == std::string::npos)
        throw Error("cannot parse meta.position attribute '%s'", pos);

    std::string filename(pos, 0, colon);
    unsigned int lineno;
    try {
        lineno = std::stoi(std::string(pos, colon + 1));
    } catch (std::invalid_argument & e) {
        throw Error("cannot parse line number '%s'", pos);
    }

    Symbol file = state.symbols.create(filename);

    return { file, lineno, 0 };
}

}
<|endoftext|>