<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <ctype.h>

#include "MetaFileLib.h"

char sepChar = '=';

//
bool MF_SkipToVal(std::ifstream &fp)
  {
  char c;
  if( fp.eof() )
  {
    return false;
  }
  c = fp.get();
  while( c != sepChar && !fp.eof() )
  {
    c = fp.get();
  }

  if( fp.eof() )
    {
    std::cout << "Incomplete file record definition" << std::endl;
    return false;
    }
  return true;
  }

//
bool MF_IsComplete(int nFields, MF_FieldRec *field)
   {
   int i;
   for(i=0; i<nFields; i++)
    if(field[i].required && !field[i].defined)
      {
      std::cout << field[i].name << " required and not defined." << std::endl;
      return false;
      }
   return true;
   }

//
//bool MF_Read(FILE *fp, int nFields, MF_FieldRec *field, int fTerm, bool fromTopOfFile, char _sepChar)
bool MF_Read(std::ifstream &fp, int nFields, MF_FieldRec *field, int fTerm, bool fromTopOfFile, char _sepChar)
  {
  char s[255];
  int i, j;
  for(i=0; i<nFields; i++)
  {
    field[i].defined = false;
  }

   sepChar = _sepChar;

  int found;

   if(fromTopOfFile)
   {
     fp.seekg( 0, std::ios::beg ); //      fseek(fp, 0, SEEK_SET);
   }

  while(1)
    {
    fp.get( s, 255, sepChar );
    if( fp.eof() )
    {
      return MF_IsComplete(nFields, field);
    }

    i = strlen( s )-1;
    while((s[i] == sepChar || s[i] == ' ' || s[i] == '\t' || s[i] == '\n') && i>0)
    {
      s[i--] = '\0';
    }
    if( fp.eof() )
    {
      return MF_IsComplete(nFields, field);
    }

    found = 0;
    for(i=0; i<nFields; i++)
    {
      if(!strcmp(field[i].name, s))
        {
        if(field[i].dependsOn >= 0)
          if(!field[field[i].dependsOn].defined)
            {
            std::cout << field[i].name << " defined prior to defining " << field[field[i].dependsOn].name << std::endl;
            return false;
            }
        switch(field[i].type)
          {
          case MF_NONE:
            if( !fp.eof() )
            {
              fp.get();
            }
            break;
          case MF_CHAR:
            {
            MF_SkipToVal(fp);
            char c = fp.get();
            field[i].val[0] = (float)c;
            fp.getline( s,500 );
            break;
            }
          default:
          case MF_INT:
            {
            MF_SkipToVal(fp);
            fp >> field[i].val[0];
            fp.getline( s,500 );
            break;
            }
          case MF_FLOAT:
            MF_SkipToVal(fp);
            fp >> field[i].val[0];
            fp.getline( s,500 );
            break;
          case MF_CHAR_ARRAY:
            MF_SkipToVal(fp);
            if(field[i].dependsOn >= 0)
                     {
                     field[i].length = (int)(field[field[i].dependsOn].val[0]);
                     fp.read( (char *)field[i].val, field[i].length+1 );
                     }
              else
                     {
                     char * str = (char *)field[i].val;
                     fp.getline(str,500);
                     char * start = str;
                     while( isspace( *start ) ) start++;
                     char * compact = str;
                     while( *start && *start != '\r' )
                     {
                       *compact = *start;
                       start++;
                       compact++;
                     }
                     *compact = '\0';
                     field[i].length = strlen( str );
                     strcpy( (char *)(field[i].val), str );
                     }
            break;
          case MF_INT_ARRAY:
            {
            MF_SkipToVal(fp);
            if(field[i].dependsOn >= 0)
             {
              field[i].length = (int)field[field[i].dependsOn].val[0];
              for(j=0; j<field[i].length; j++)
              {
                fp >> field[i].val[j];
              }
             }
             else
             {
               if(field[i].length <= 0)
               {
                 std::cout << "Int arrays must have dependency" << std::endl;
                 return false;
               }
               for(j=0; j<field[i].length; j++)
               {
                 fp >> field[i].val[j];
               }
              }
              fp.getline( s,500 );
            break;
            }
          case MF_FLOAT_ARRAY:
            {
            MF_SkipToVal(fp);
            if(field[i].dependsOn >= 0)
             {
              field[i].length = (int)field[field[i].dependsOn].val[0];
              for(j=0; j<field[i].length; j++)
              {
                fp >> field[i].val[j];
              }
             }
             else
             {
               if(field[i].length <= 0)
               {
                 std::cout << "Float arrays must have dependency" << std::endl;
                 return false;
               }
               for(j=0; j<field[i].length; j++)
               {
                 fp >> field[i].val[j];
               }
              }
              fp.getline( s,500 );
            break;
            }
          }
          found = 1;
          field[i].defined = true;
          if((int)i == fTerm)
          {
            return MF_IsComplete(nFields, field);
          }
        }
        if( found )
        {
          break;
        }
      }

    }

  return true;
  }

//
bool MF_Write(std::ofstream &fp, int nFields, MF_FieldRec *field, char _sepChar)
   {
   sepChar = _sepChar;

   int i, j;
   for(i=0; i<nFields; i++)
      {
      switch(field[i].type)
         {
         case MF_NONE:
            fp << field[i].name << std::endl;
            break;
         case MF_CHAR:
            fp << field[i].name << " " << sepChar << " " << (char)field[i].val[0] << std::endl;
            break;
         case MF_INT:
            fp << field[i].name << " " << sepChar << " " << (int)field[i].val[0] << std::endl;
            break;
         case MF_FLOAT:
            fp << field[i].name << " " << sepChar << " " << (float)field[i].val[0] << std::endl;
            break;
         case MF_CHAR_ARRAY:
            fp << field[i].name << " " << sepChar;
            if(field[i].dependsOn >= 0)
            {
               if(field[i].length != field[field[i].dependsOn].val[0])
               {
                  std::cout << "Warning: length and dependsOn values not equal in write" << std::endl;
               }
            }
            char temp_str[80] ;
            for (j = 0 ; j < field[i].length ; j++)
              temp_str[j] = (char) field[i].val[j] ;
            fp.write(temp_str, field[i].length );
            fp << std::endl;
            break;
         case MF_INT_ARRAY:
            fp << field[i].name << " " << sepChar;
            if(field[i].dependsOn >= 0)
            {
               if(field[i].length != field[field[i].dependsOn].val[0])
               {
                  std::cout << "Warning: length and dependsOn values not equal in write" << std::endl;
               }
            }
            for(j=0; j<field[i].length; j++)
            {
              fp << " " << (int)field[i].val[j];
            }
            fp << std::endl;
            break;
      case MF_FLOAT_ARRAY:
            fp << field[i].name << " " << sepChar;
            if(field[i].dependsOn >= 0)
            {
               if(field[i].length != field[field[i].dependsOn].val[0])
               {
                  std::cout << "Warning: length and dependsOn values not equal in write" << std::endl;
               }
            }
            for(j=0; j<field[i].length; j++)
            {
              fp << " " << (float)field[i].val[j];
            }
            fp << std::endl;
        break;
         }
      }
   return true;
   }

bool MF_ParseStringToCHAR_ARRAY(char *s, int *n, char ***val)
{
    int l = strlen(s);

    int p = 0;
    while(p<l && s[p] == ' ')
        p++;

    sscanf(&s[p], "%d ", n);
    while(p<l && s[p] != ' ')
        p++;

    *val = new char*[*n];

    int i, j;
    for(i=0; i<*n; i++) {
        if(p == l)
            return false;
        (*val)[i] = new char [80];
        while(p<l && s[p] == ' ')
            p++;
        j = 0;
        while(p<l && s[p] != ' ')
            (*val)[i][j++] = s[p++];
        (*val)[i][j] = '\0';
    }

    return true;

}

bool WriteFieldToFile(std::ofstream & _fp, const char *_fieldName,
                       MF_ValType _pType, int _n, const void *_v)
{
  int i;
  MF_FieldRec f;

  sprintf(f.name, "%s", _fieldName);
  f.defined = false;
  f.dependsOn = -1;
  f.length = _n;
  f.required = false;
  f.type = _pType;
  switch(_pType)
  {
    case MF_CHAR_ARRAY:
    case MF_CHAR:
      for(i = 0; i < _n; i++)
      {
        f.val[i] = (float)(((char *)_v)[i]);
      }
      break;
    case MF_INT:
    case MF_INT_ARRAY:
      for(i=0; i<_n; i++)
      {
        f.val[i] = (float)(((int *)_v)[i]);
      }
      break;
    case MF_FLOAT:
    case MF_FLOAT_ARRAY:
      for(i=0; i<_n; i++)
      {
        f.val[i] = ((float *)_v)[i];
      }
      break;
    default:
      break;
  }

  MF_Write(_fp, 1, &f);

  return true;
}

bool WriteFieldToFile(std::ofstream & _fp, const char *_fieldName,
                      MF_ValType _pType, float _v)
{
  MF_FieldRec f;

  sprintf(f.name, "%s", _fieldName);
  f.defined = false;
  f.dependsOn = -1;
  f.length = 1;
  f.required = false;
  f.type = _pType;
  f.val[0] = _v;

  MF_Write(_fp, 1, &f);

  return true;
}

<commit_msg>FIX: space character was missing after separation character sepChar in writing.<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <ctype.h>

#include "MetaFileLib.h"

char sepChar = '=';

//
bool MF_SkipToVal(std::ifstream &fp)
  {
  char c;
  if( fp.eof() )
  {
    return false;
  }
  c = fp.get();
  while( c != sepChar && !fp.eof() )
  {
    c = fp.get();
  }

  if( fp.eof() )
    {
    std::cout << "Incomplete file record definition" << std::endl;
    return false;
    }
  return true;
  }

//
bool MF_IsComplete(int nFields, MF_FieldRec *field)
   {
   int i;
   for(i=0; i<nFields; i++)
    if(field[i].required && !field[i].defined)
      {
      std::cout << field[i].name << " required and not defined." << std::endl;
      return false;
      }
   return true;
   }

//
//bool MF_Read(FILE *fp, int nFields, MF_FieldRec *field, int fTerm, bool fromTopOfFile, char _sepChar)
bool MF_Read(std::ifstream &fp, int nFields, MF_FieldRec *field, int fTerm, bool fromTopOfFile, char _sepChar)
  {
  char s[255];
  int i, j;
  for(i=0; i<nFields; i++)
  {
    field[i].defined = false;
  }

   sepChar = _sepChar;

  int found;

   if(fromTopOfFile)
   {
     fp.seekg( 0, std::ios::beg ); //      fseek(fp, 0, SEEK_SET);
   }

  while(1)
    {
    fp.get( s, 255, sepChar );
    if( fp.eof() )
    {
      return MF_IsComplete(nFields, field);
    }

    i = strlen( s )-1;
    while((s[i] == sepChar || s[i] == ' ' || s[i] == '\t' || s[i] == '\n') && i>0)
    {
      s[i--] = '\0';
    }
    if( fp.eof() )
    {
      return MF_IsComplete(nFields, field);
    }

    found = 0;
    for(i=0; i<nFields; i++)
    {
      if(!strcmp(field[i].name, s))
        {
        if(field[i].dependsOn >= 0)
          if(!field[field[i].dependsOn].defined)
            {
            std::cout << field[i].name << " defined prior to defining " << field[field[i].dependsOn].name << std::endl;
            return false;
            }
        switch(field[i].type)
          {
          case MF_NONE:
            if( !fp.eof() )
            {
              fp.get();
            }
            break;
          case MF_CHAR:
            {
            MF_SkipToVal(fp);
            char c = fp.get();
            field[i].val[0] = (float)c;
            fp.getline( s,500 );
            break;
            }
          default:
          case MF_INT:
            {
            MF_SkipToVal(fp);
            fp >> field[i].val[0];
            fp.getline( s,500 );
            break;
            }
          case MF_FLOAT:
            MF_SkipToVal(fp);
            fp >> field[i].val[0];
            fp.getline( s,500 );
            break;
          case MF_CHAR_ARRAY:
            MF_SkipToVal(fp);
            if(field[i].dependsOn >= 0)
                     {
                     field[i].length = (int)(field[field[i].dependsOn].val[0]);
                     fp.read( (char *)field[i].val, field[i].length+1 );
                     }
              else
                     {
                     char * str = (char *)field[i].val;
                     fp.getline(str,500);
                     char * start = str;
                     while( isspace( *start ) ) start++;
                     char * compact = str;
                     while( *start && *start != '\r' )
                     {
                       *compact = *start;
                       start++;
                       compact++;
                     }
                     *compact = '\0';
                     field[i].length = strlen( str );
                     strcpy( (char *)(field[i].val), str );
                     }
            break;
          case MF_INT_ARRAY:
            {
            MF_SkipToVal(fp);
            if(field[i].dependsOn >= 0)
             {
              field[i].length = (int)field[field[i].dependsOn].val[0];
              for(j=0; j<field[i].length; j++)
              {
                fp >> field[i].val[j];
              }
             }
             else
             {
               if(field[i].length <= 0)
               {
                 std::cout << "Int arrays must have dependency" << std::endl;
                 return false;
               }
               for(j=0; j<field[i].length; j++)
               {
                 fp >> field[i].val[j];
               }
              }
              fp.getline( s,500 );
            break;
            }
          case MF_FLOAT_ARRAY:
            {
            MF_SkipToVal(fp);
            if(field[i].dependsOn >= 0)
             {
              field[i].length = (int)field[field[i].dependsOn].val[0];
              for(j=0; j<field[i].length; j++)
              {
                fp >> field[i].val[j];
              }
             }
             else
             {
               if(field[i].length <= 0)
               {
                 std::cout << "Float arrays must have dependency" << std::endl;
                 return false;
               }
               for(j=0; j<field[i].length; j++)
               {
                 fp >> field[i].val[j];
               }
              }
              fp.getline( s,500 );
            break;
            }
          }
          found = 1;
          field[i].defined = true;
          if((int)i == fTerm)
          {
            return MF_IsComplete(nFields, field);
          }
        }
        if( found )
        {
          break;
        }
      }

    }

  return true;
  }

//
bool MF_Write(std::ofstream &fp, int nFields, MF_FieldRec *field, char _sepChar)
   {
   sepChar = _sepChar;

   int i, j;
   for(i=0; i<nFields; i++)
      {
      switch(field[i].type)
         {
         case MF_NONE:
            fp << field[i].name << std::endl;
            break;
         case MF_CHAR:
            fp << field[i].name << " " << sepChar << " " << (char)field[i].val[0] << std::endl;
            break;
         case MF_INT:
            fp << field[i].name << " " << sepChar << " " << (int)field[i].val[0] << std::endl;
            break;
         case MF_FLOAT:
            fp << field[i].name << " " << sepChar << " " << (float)field[i].val[0] << std::endl;
            break;
         case MF_CHAR_ARRAY:
            fp << field[i].name << " " << sepChar << " ";
            if(field[i].dependsOn >= 0)
            {
               if(field[i].length != field[field[i].dependsOn].val[0])
               {
                  std::cout << "Warning: length and dependsOn values not equal in write" << std::endl;
               }
            }
            char temp_str[80] ;
            for (j = 0 ; j < field[i].length ; j++)
              temp_str[j] = (char) field[i].val[j] ;
            fp.write(temp_str, field[i].length );
            fp << std::endl;
            break;
         case MF_INT_ARRAY:
            fp << field[i].name << " " << sepChar << " ";
            if(field[i].dependsOn >= 0)
            {
               if(field[i].length != field[field[i].dependsOn].val[0])
               {
                  std::cout << "Warning: length and dependsOn values not equal in write" << std::endl;
               }
            }
            for(j=0; j<field[i].length; j++)
            {
              fp << " " << (int)field[i].val[j];
            }
            fp << std::endl;
            break;
      case MF_FLOAT_ARRAY:
            fp << field[i].name << " " << sepChar << " ";
            if(field[i].dependsOn >= 0)
            {
               if(field[i].length != field[field[i].dependsOn].val[0])
               {
                  std::cout << "Warning: length and dependsOn values not equal in write" << std::endl;
               }
            }
            for(j=0; j<field[i].length; j++)
            {
              fp << " " << (float)field[i].val[j];
            }
            fp << std::endl;
        break;
         }
      }
   return true;
   }

bool MF_ParseStringToCHAR_ARRAY(char *s, int *n, char ***val)
{
    int l = strlen(s);

    int p = 0;
    while(p<l && s[p] == ' ')
        p++;

    sscanf(&s[p], "%d ", n);
    while(p<l && s[p] != ' ')
        p++;

    *val = new char*[*n];

    int i, j;
    for(i=0; i<*n; i++) {
        if(p == l)
            return false;
        (*val)[i] = new char [80];
        while(p<l && s[p] == ' ')
            p++;
        j = 0;
        while(p<l && s[p] != ' ')
            (*val)[i][j++] = s[p++];
        (*val)[i][j] = '\0';
    }

    return true;

}

bool WriteFieldToFile(std::ofstream & _fp, const char *_fieldName,
                       MF_ValType _pType, int _n, const void *_v)
{
  int i;
  MF_FieldRec f;

  sprintf(f.name, "%s", _fieldName);
  f.defined = false;
  f.dependsOn = -1;
  f.length = _n;
  f.required = false;
  f.type = _pType;
  switch(_pType)
  {
    case MF_CHAR_ARRAY:
    case MF_CHAR:
      for(i = 0; i < _n; i++)
      {
        f.val[i] = (float)(((char *)_v)[i]);
      }
      break;
    case MF_INT:
    case MF_INT_ARRAY:
      for(i=0; i<_n; i++)
      {
        f.val[i] = (float)(((int *)_v)[i]);
      }
      break;
    case MF_FLOAT:
    case MF_FLOAT_ARRAY:
      for(i=0; i<_n; i++)
      {
        f.val[i] = ((float *)_v)[i];
      }
      break;
    default:
      break;
  }

  MF_Write(_fp, 1, &f);

  return true;
}

bool WriteFieldToFile(std::ofstream & _fp, const char *_fieldName,
                      MF_ValType _pType, float _v)
{
  MF_FieldRec f;

  sprintf(f.name, "%s", _fieldName);
  f.defined = false;
  f.dependsOn = -1;
  f.length = 1;
  f.required = false;
  f.type = _pType;
  f.val[0] = _v;

  MF_Write(_fp, 1, &f);

  return true;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <sstream>

#include "msgpack_wrapper.h"

#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include "xchange/rapidjson.hpp"

#include "log.h"

MsgPack::MsgPack()
	: handler(std::make_shared<object_handle>()),
	  obj(handler->obj) { }

MsgPack::MsgPack(const std::shared_ptr<object_handle>& unpacked, msgpack::object& o)
	: handler(unpacked),
	  obj(o) { }

MsgPack::MsgPack(const msgpack::object& o, std::unique_ptr<msgpack::zone>&& z)
	: handler(std::make_shared<object_handle>(o, std::move(z))),
	  obj(handler->obj) { }

MsgPack::MsgPack(msgpack::unpacked& u)
	: handler(std::make_shared<object_handle>(u.get(), std::move(u.zone()))),
	  obj(handler->obj) { }

MsgPack::MsgPack(const std::string& buffer)
	: handler(make_handler(buffer)),
	  obj(handler->obj) { }

MsgPack::MsgPack(const rapidjson::Document& doc)
	: handler(make_handler(doc)),
	  obj(handler->obj) { }

MsgPack::MsgPack(MsgPack&& other) noexcept
	: handler(std::move(other.handler)),
	  obj(handler->obj) { }

MsgPack::MsgPack(const MsgPack& other)
	: handler(other.handler),
	  obj(handler->obj) { }

std::shared_ptr<MsgPack::object_handle>
MsgPack::make_handler()
{
	return std::make_shared<MsgPack::object_handle>();
}

std::shared_ptr<MsgPack::object_handle>
MsgPack::make_handler(const std::string& buffer)
{
	msgpack::unpacked u;
	msgpack::unpack(&u, buffer.data(), buffer.size());
	return std::make_shared<MsgPack::object_handle>(u.get(), msgpack::move(u.zone()));
}

std::shared_ptr<MsgPack::object_handle>
MsgPack::make_handler(const rapidjson::Document& doc)
{
	auto zone(std::make_unique<msgpack::zone>());
	msgpack::object obj(doc, *zone.get());
	return std::make_shared<MsgPack::object_handle>(obj, msgpack::move(zone));
}

MsgPack
MsgPack::operator[](const MsgPack& o)
{
	if (o.obj.type == msgpack::type::STR) {
		return operator[](std::string(o.obj.via.str.ptr, o.obj.via.str.size));
	}
	if (o.obj.type == msgpack::type::POSITIVE_INTEGER) {
		return operator[](static_cast<uint32_t>(o.obj.via.u64));
	}
	throw msgpack::type_error();
}

MsgPack
MsgPack::operator[](const std::string& key)
{
	if (obj.type == msgpack::type::NIL) {
		obj.type = msgpack::type::MAP;
		obj.via.map.ptr = nullptr;
		obj.via.map.size = 0;
		obj.via.map.m_alloc = 0;
	}

	if (obj.type == msgpack::type::MAP) {
		const msgpack::object_kv* pend(obj.via.map.ptr + obj.via.map.size);
		for (auto p = obj.via.map.ptr; p != pend; ++p) {
			if (p->key.type == msgpack::type::STR) {
				if (key.compare(std::string(p->key.via.str.ptr, p->key.via.str.size)) == 0) {
					return MsgPack(handler, p->val);
				}
			}
		}

		expand_map();
		msgpack::object_kv* np(obj.via.map.ptr + obj.via.map.size);

		msgpack::detail::unpack_str(handler->user, key.data(), (uint32_t)key.size(), np->key);
		msgpack::detail::unpack_nil(np->val);
		msgpack::detail::unpack_map_item(obj, np->key, np->val);

		return MsgPack(handler, np->val);
	}

	throw msgpack::type_error();
}

MsgPack
MsgPack::operator[](uint32_t off)
{
	if (obj.type == msgpack::type::NIL) {
		obj.type = msgpack::type::ARRAY;
		obj.via.array.ptr = nullptr;
		obj.via.array.size = 0;
		obj.via.array.m_alloc = 0;
	}

	if (obj.type == msgpack::type::ARRAY) {
		auto r_size = off + 1;
		if (obj.via.array.size < r_size) {
			expand_array(r_size);

			// Initialize new elements.
			const msgpack::object* npend(obj.via.array.ptr + r_size);
			for (auto np = obj.via.array.ptr + obj.via.array.size; np != npend; ++np) {
				msgpack::detail::unpack_nil(*np);
				msgpack::detail::unpack_array_item(obj, *np);
			}
		}

		return MsgPack(handler, obj.via.array.ptr[off]);
	}

	throw msgpack::type_error();
}

MsgPack
MsgPack::at(const MsgPack& o) const
{
	if (o.obj.type == msgpack::type::STR) {
		return at(std::string(o.obj.via.str.ptr, o.obj.via.str.size));
	}
	if (o.obj.type == msgpack::type::POSITIVE_INTEGER) {
		return at(static_cast<uint32_t>(o.obj.via.u64));
	}
	throw msgpack::type_error();
}

MsgPack
MsgPack::at(const std::string& key) const
{
	if (obj.type == msgpack::type::NIL) {
		throw std::out_of_range(key);
	}

	if (obj.type == msgpack::type::MAP) {
		const msgpack::object_kv* pend(obj.via.map.ptr + obj.via.map.size);
		for (auto p = obj.via.map.ptr; p != pend; ++p) {
			if (p->key.type == msgpack::type::STR) {
				if (key == std::string(p->key.via.str.ptr, p->key.via.str.size)) {
					return MsgPack(handler, p->val);
				}
			}
		}

		throw std::out_of_range(key);
	}

	throw msgpack::type_error();
}

MsgPack
MsgPack::at(uint32_t off) const
{
	if (obj.type == msgpack::type::NIL) {
		throw std::out_of_range(std::to_string(off));
	}

	if (obj.type == msgpack::type::ARRAY) {
		if (off < obj.via.array.size) {
			return MsgPack(handler, obj.via.array.ptr[off]);
		}

		throw std::out_of_range(std::to_string(off));
	}

	throw msgpack::type_error();
}

std::string
MsgPack::key() const
{
	if (obj.via.map.ptr->key.type == msgpack::type::STR) {
		return std::string(obj.via.map.ptr->key.via.str.ptr, obj.via.map.ptr->key.via.str.size);
	}
	return std::string();
}

std::string
MsgPack::to_json_string(bool prettify)
{
	if (prettify) {
		rapidjson::Document doc = to_json();
		rapidjson::StringBuffer buffer;
		rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
		doc.Accept(writer);
		return std::string(buffer.GetString(), buffer.GetSize());
	} else {
		std::ostringstream oss;
		oss << obj;
		return oss.str();
	}
}

rapidjson::Document
MsgPack::to_json()
{
	rapidjson::Document doc;
	obj.convert(&doc);
	return doc;
}

std::string
MsgPack::to_string()
{
	msgpack::sbuffer sbuf;
	msgpack::pack(&sbuf, obj);
	return std::string(sbuf.data(), sbuf.size());
}

void
MsgPack::expand_map()
{
	if (obj.via.map.m_alloc == obj.via.map.size) {
		size_t nsize = obj.via.map.m_alloc > 0 ? obj.via.map.m_alloc * 2 : MSGPACK_MAP_INIT_SIZE;

		const msgpack::object_kv* p(obj.via.map.ptr);
		const msgpack::object_kv* pend(obj.via.map.ptr + obj.via.map.size);

		msgpack::detail::unpack_map()(handler->user, nsize, obj);

		// Copy previous memory.
		for ( ; p != pend; ++p) {
			msgpack::detail::unpack_map_item(obj, p->key, p->val);
		}

		obj.via.map.m_alloc = nsize;
	}
}

void
MsgPack::expand_array(size_t r_size)
{
	if (obj.via.array.m_alloc < r_size) {
		size_t nsize = obj.via.array.m_alloc > 0 ? obj.via.array.m_alloc * 2 : MSGPACK_ARRAY_INIT_SIZE;
		while (nsize < r_size) {
			nsize *= 2;
		}

		const msgpack::object* p(obj.via.array.ptr);
		const msgpack::object* pend(obj.via.array.ptr + obj.via.array.size);

		msgpack::detail::unpack_array()(handler->user, nsize, obj);

		// Copy previous memory.
		for ( ; p != pend; ++p) {
			msgpack::detail::unpack_array_item(obj, *p);
		}

		obj.via.array.m_alloc = nsize;
	}
}

size_t
MsgPack::capacity() const noexcept
{
	switch (obj.type) {
		case msgpack::type::MAP:
			return obj.via.map.m_alloc;
			break;
		case msgpack::type::ARRAY:
			return obj.via.array.m_alloc;
			break;
		default:
			return 0;
	}
}

bool
MsgPack::erase(const std::string& key)
{
	if (obj.type == msgpack::type::MAP) {
		size_t size = obj.via.map.size;
		const msgpack::object_kv* pend(obj.via.map.ptr + obj.via.map.size);
		for (auto p = obj.via.map.ptr; p != pend; ++p) {
			if (p->key.type == msgpack::type::STR) {
				--size;
				if (key.compare(std::string(p->key.via.str.ptr, p->key.via.str.size)) == 0) {
					memcpy(p, p + 1, size * sizeof(msgpack::object_kv));
					--obj.via.map.size;
					return true;
				}
			}
		}
		return false;
	}

	throw msgpack::type_error();
}

namespace msgpack {
	MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
		namespace adaptor {
			const msgpack::object& convert<MsgPack>::operator()(const msgpack::object& o, MsgPack& v) const {
				v = MsgPack(o, std::make_unique<msgpack::zone>());
				return o;
			}

			template <typename Stream>
			msgpack::packer<Stream>& pack<MsgPack>::operator()(msgpack::packer<Stream>& o, const MsgPack& v) const {
				o << v;
				return o;
			}

			void object<MsgPack>::operator()(msgpack::object& o, const MsgPack& v) const {
				msgpack::object obj(v.obj);
				o.type = obj.type;
				o.via = obj.via;
			}

			void object_with_zone<MsgPack>::operator()(msgpack::object::with_zone& o, const MsgPack& v) const {
				msgpack::object obj(v.obj, o.zone);
				o.type = obj.type;
				o.via = obj.via;
			}
		} // namespace adaptor
	} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack
<commit_msg>Format and fixing bug<commit_after>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <sstream>

#include "msgpack_wrapper.h"

#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include "xchange/rapidjson.hpp"

#include "log.h"

MsgPack::MsgPack()
	: handler(std::make_shared<object_handle>()),
	  obj(handler->obj) { }

MsgPack::MsgPack(const std::shared_ptr<object_handle>& unpacked, msgpack::object& o)
	: handler(unpacked),
	  obj(o) { }

MsgPack::MsgPack(const msgpack::object& o, std::unique_ptr<msgpack::zone>&& z)
	: handler(std::make_shared<object_handle>(o, std::move(z))),
	  obj(handler->obj) { }

MsgPack::MsgPack(msgpack::unpacked& u)
	: handler(std::make_shared<object_handle>(u.get(), std::move(u.zone()))),
	  obj(handler->obj) { }

MsgPack::MsgPack(const std::string& buffer)
	: handler(make_handler(buffer)),
	  obj(handler->obj) { }

MsgPack::MsgPack(const rapidjson::Document& doc)
	: handler(make_handler(doc)),
	  obj(handler->obj) { }

MsgPack::MsgPack(MsgPack&& other) noexcept
	: handler(std::move(other.handler)),
	  obj(handler->obj) { }

MsgPack::MsgPack(const MsgPack& other)
	: handler(other.handler),
	  obj(handler->obj) { }

std::shared_ptr<MsgPack::object_handle>
MsgPack::make_handler()
{
	return std::make_shared<MsgPack::object_handle>();
}

std::shared_ptr<MsgPack::object_handle>
MsgPack::make_handler(const std::string& buffer)
{
	msgpack::unpacked u;
	msgpack::unpack(&u, buffer.data(), buffer.size());
	return std::make_shared<MsgPack::object_handle>(u.get(), msgpack::move(u.zone()));
}

std::shared_ptr<MsgPack::object_handle>
MsgPack::make_handler(const rapidjson::Document& doc)
{
	auto zone(std::make_unique<msgpack::zone>());
	msgpack::object obj(doc, *zone.get());
	return std::make_shared<MsgPack::object_handle>(obj, msgpack::move(zone));
}

MsgPack
MsgPack::operator[](const MsgPack& o)
{
	if (o.obj.type == msgpack::type::STR) {
		return operator[](std::string(o.obj.via.str.ptr, o.obj.via.str.size));
	}
	if (o.obj.type == msgpack::type::POSITIVE_INTEGER) {
		return operator[](static_cast<uint32_t>(o.obj.via.u64));
	}
	throw msgpack::type_error();
}

MsgPack
MsgPack::operator[](const std::string& key)
{
	if (obj.type == msgpack::type::NIL) {
		obj.type = msgpack::type::MAP;
		obj.via.map.ptr = nullptr;
		obj.via.map.size = 0;
		obj.via.map.m_alloc = 0;
	}

	if (obj.type == msgpack::type::MAP) {
		const msgpack::object_kv* pend(obj.via.map.ptr + obj.via.map.size);
		for (auto p = obj.via.map.ptr; p != pend; ++p) {
			if (p->key.type == msgpack::type::STR) {
				if (key.compare(std::string(p->key.via.str.ptr, p->key.via.str.size)) == 0) {
					return MsgPack(handler, p->val);
				}
			}
		}

		expand_map();
		msgpack::object_kv* np(obj.via.map.ptr + obj.via.map.size);

		msgpack::detail::unpack_str(handler->user, key.data(), (uint32_t)key.size(), np->key);
		msgpack::detail::unpack_nil(np->val);
		msgpack::detail::unpack_map_item(obj, np->key, np->val);

		return MsgPack(handler, np->val);
	}

	throw msgpack::type_error();
}

MsgPack
MsgPack::operator[](uint32_t off)
{
	if (obj.type == msgpack::type::NIL) {
		obj.type = msgpack::type::ARRAY;
		obj.via.array.ptr = nullptr;
		obj.via.array.size = 0;
		obj.via.array.m_alloc = 0;
	}

	if (obj.type == msgpack::type::ARRAY) {
		auto r_size = off + 1;
		if (obj.via.array.size < r_size) {
			expand_array(r_size);

			// Initialize new elements.
			const msgpack::object* npend(obj.via.array.ptr + r_size);
			for (auto np = obj.via.array.ptr + obj.via.array.size; np != npend; ++np) {
				msgpack::detail::unpack_nil(*np);
				msgpack::detail::unpack_array_item(obj, *np);
			}
		}

		return MsgPack(handler, obj.via.array.ptr[off]);
	}

	throw msgpack::type_error();
}

MsgPack
MsgPack::at(const MsgPack& o) const
{
	if (o.obj.type == msgpack::type::STR) {
		return at(std::string(o.obj.via.str.ptr, o.obj.via.str.size));
	}
	if (o.obj.type == msgpack::type::POSITIVE_INTEGER) {
		return at(static_cast<uint32_t>(o.obj.via.u64));
	}
	throw msgpack::type_error();
}

MsgPack
MsgPack::at(const std::string& key) const
{
	if (obj.type == msgpack::type::NIL) {
		throw std::out_of_range(key);
	}

	if (obj.type == msgpack::type::MAP) {
		const msgpack::object_kv* pend(obj.via.map.ptr + obj.via.map.size);
		for (auto p = obj.via.map.ptr; p != pend; ++p) {
			if (p->key.type == msgpack::type::STR) {
				if (key.compare(std::string(p->key.via.str.ptr, p->key.via.str.size)) == 0)  {
					return MsgPack(handler, p->val);
				}
			}
		}

		throw std::out_of_range(key);
	}

	throw msgpack::type_error();
}

MsgPack
MsgPack::at(uint32_t off) const
{
	if (obj.type == msgpack::type::NIL) {
		throw std::out_of_range(std::to_string(off));
	}

	if (obj.type == msgpack::type::ARRAY) {
		if (off < obj.via.array.size) {
			return MsgPack(handler, obj.via.array.ptr[off]);
		}

		throw std::out_of_range(std::to_string(off));
	}

	throw msgpack::type_error();
}

std::string
MsgPack::key() const
{
	if (obj.via.map.ptr->key.type == msgpack::type::STR) {
		return std::string(obj.via.map.ptr->key.via.str.ptr, obj.via.map.ptr->key.via.str.size);
	}
	return std::string();
}

std::string
MsgPack::to_json_string(bool prettify)
{
	if (prettify) {
		rapidjson::Document doc = to_json();
		rapidjson::StringBuffer buffer;
		rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
		doc.Accept(writer);
		return std::string(buffer.GetString(), buffer.GetSize());
	} else {
		std::ostringstream oss;
		oss << obj;
		return oss.str();
	}
}

rapidjson::Document
MsgPack::to_json()
{
	rapidjson::Document doc;
	obj.convert(&doc);
	return doc;
}

std::string
MsgPack::to_string()
{
	msgpack::sbuffer sbuf;
	msgpack::pack(&sbuf, obj);
	return std::string(sbuf.data(), sbuf.size());
}

void
MsgPack::expand_map()
{
	if (obj.via.map.m_alloc == obj.via.map.size) {
		size_t nsize = obj.via.map.m_alloc > 0 ? obj.via.map.m_alloc * 2 : MSGPACK_MAP_INIT_SIZE;

		const msgpack::object_kv* p(obj.via.map.ptr);
		const msgpack::object_kv* pend(obj.via.map.ptr + obj.via.map.size);

		msgpack::detail::unpack_map()(handler->user, nsize, obj);

		// Copy previous memory.
		for ( ; p != pend; ++p) {
			msgpack::detail::unpack_map_item(obj, p->key, p->val);
		}

		obj.via.map.m_alloc = nsize;
	}
}

void
MsgPack::expand_array(size_t r_size)
{
	if (obj.via.array.m_alloc < r_size) {
		size_t nsize = obj.via.array.m_alloc > 0 ? obj.via.array.m_alloc * 2 : MSGPACK_ARRAY_INIT_SIZE;
		while (nsize < r_size) {
			nsize *= 2;
		}

		const msgpack::object* p(obj.via.array.ptr);
		const msgpack::object* pend(obj.via.array.ptr + obj.via.array.size);

		msgpack::detail::unpack_array()(handler->user, nsize, obj);

		// Copy previous memory.
		for ( ; p != pend; ++p) {
			msgpack::detail::unpack_array_item(obj, *p);
		}

		obj.via.array.m_alloc = nsize;
	}
}

size_t
MsgPack::capacity() const noexcept
{
	switch (obj.type) {
		case msgpack::type::MAP:
			return obj.via.map.m_alloc;
			break;
		case msgpack::type::ARRAY:
			return obj.via.array.m_alloc;
			break;
		default:
			return 0;
	}
}

bool
MsgPack::erase(const std::string& key)
{
	if (obj.type == msgpack::type::MAP) {
		size_t size = obj.via.map.size;
		const msgpack::object_kv* pend(obj.via.map.ptr + obj.via.map.size);
		for (auto p = obj.via.map.ptr; p != pend; ++p) {
			--size;
			if (p->key.type == msgpack::type::STR) {
				if (key.compare(std::string(p->key.via.str.ptr, p->key.via.str.size)) == 0) {
					memcpy(p, p + 1, size * sizeof(msgpack::object_kv));
					--obj.via.map.size;
					return true;
				}
			}
		}
		return false;
	}

	throw msgpack::type_error();
}

namespace msgpack {
	MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
		namespace adaptor {
			const msgpack::object& convert<MsgPack>::operator()(const msgpack::object& o, MsgPack& v) const {
				v = MsgPack(o, std::make_unique<msgpack::zone>());
				return o;
			}

			template <typename Stream>
			msgpack::packer<Stream>& pack<MsgPack>::operator()(msgpack::packer<Stream>& o, const MsgPack& v) const {
				o << v;
				return o;
			}

			void object<MsgPack>::operator()(msgpack::object& o, const MsgPack& v) const {
				msgpack::object obj(v.obj);
				o.type = obj.type;
				o.via = obj.via;
			}

			void object_with_zone<MsgPack>::operator()(msgpack::object::with_zone& o, const MsgPack& v) const {
				msgpack::object obj(v.obj, o.zone);
				o.type = obj.type;
				o.via = obj.via;
			}
		} // namespace adaptor
	} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack
<|endoftext|>


<commit_before>#ifndef STAN__AGRAD__REV__FUNCTIONS__LOG_FALLING_FACTORIAL_HPP
#define STAN__AGRAD__REV__FUNCTIONS__LOG_FALLING_FACTORIAL_HPP

#include <stan/agrad/rev/var.hpp>
#include <stan/agrad/rev/internal/vd_vari.hpp>
#include <stan/agrad/rev/internal/dv_vari.hpp>
#include <stan/agrad/rev/internal/vv_vari.hpp>
#include <stan/math/functions/log_falling_factorial.hpp>
#include <boost/math/special_functions/digamma.hpp>

namespace stan {
  namespace agrad {

    namespace {

      class log_falling_factorial_vv_vari : public op_vv_vari {
      public:
        log_falling_factorial_vv_vari(vari* avi, vari* bvi) :
          op_vv_vari(stan::math::log_falling_factorial(avi->val_, bvi->val_), avi, bvi) {
        }
        void chain() {
          avi_->adj_ += adj_ * boost::math::digamma(avi_->val_ + 1);
          bvi_->adj_ += adj_ * -boost::math::digamma(bvi_->val_ + 1);
        }
      };

      class log_falling_factorial_vd_vari : public op_vd_vari {
      public:
        log_falling_factorial_vd_vari(vari* avi, double b) :
          op_vd_vari(stan::math::log_falling_factorial(avi->val_, b), avi, b) {
        }
        void chain() {
          avi_->adj_ += adj_ * boost::math::digamma(avi_->val_ + 1);
        }
      };

      class log_falling_factorial_dv_vari : public op_dv_vari {
      public:
        log_falling_factorial_dv_vari(double a, vari* bvi) :
          op_dv_vari(stan::math::log_falling_factorial(a, bvi->val_), a, bvi) {
        }
        void chain() {
          bvi_->adj_ += adj_ * -boost::math::digamma(bvi_->val_ + 1);
        }
      };
    }

    inline var log_falling_factorial(const var& a,
                                     const double& b) {
      return var(new log_falling_factorial_vd_vari(a.vi_, b));
    }

    inline var log_falling_factorial(const var& a,
                                     const var& b) {
      return var(new log_falling_factorial_vv_vari(a.vi_, b.vi_));
    }

    inline var log_falling_factorial(const double& a,
                                     const var& b) {
      return var(new log_falling_factorial_dv_vari(a, b.vi_));
    }
  }
}
#endif
<commit_msg>fixed log_falling_factorial so gradient returns NaN for NaN input<commit_after>#ifndef STAN__AGRAD__REV__FUNCTIONS__LOG_FALLING_FACTORIAL_HPP
#define STAN__AGRAD__REV__FUNCTIONS__LOG_FALLING_FACTORIAL_HPP

#include <stan/agrad/rev/var.hpp>
#include <stan/agrad/rev/internal/vd_vari.hpp>
#include <stan/agrad/rev/internal/dv_vari.hpp>
#include <stan/agrad/rev/internal/vv_vari.hpp>
#include <stan/math/functions/log_falling_factorial.hpp>
#include <boost/math/special_functions/digamma.hpp>
#include <boost/math/special_functions/fpclassify.hpp>

namespace stan {
  namespace agrad {

    namespace {

      class log_falling_factorial_vv_vari : public op_vv_vari {
      public:
        log_falling_factorial_vv_vari(vari* avi, vari* bvi) :
          op_vv_vari(stan::math::log_falling_factorial(avi->val_, bvi->val_), avi, bvi) {
        }
        void chain() {
          if (unlikely(boost::math::isnan(avi_->val_)
                       || boost::math::isnan(bvi_->val_))) {
            avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
            bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
          } else {
            avi_->adj_ += adj_ * boost::math::digamma(avi_->val_ + 1);
            bvi_->adj_ += adj_ * -boost::math::digamma(bvi_->val_ + 1);
          }
        }
      };

      class log_falling_factorial_vd_vari : public op_vd_vari {
      public:
        log_falling_factorial_vd_vari(vari* avi, double b) :
          op_vd_vari(stan::math::log_falling_factorial(avi->val_, b), avi, b) {
        }
        void chain() {
          if (unlikely(boost::math::isnan(avi_->val_)
                       || boost::math::isnan(bd_)))
            avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
          else
            avi_->adj_ += adj_ * boost::math::digamma(avi_->val_ + 1);
        }
      };

      class log_falling_factorial_dv_vari : public op_dv_vari {
      public:
        log_falling_factorial_dv_vari(double a, vari* bvi) :
          op_dv_vari(stan::math::log_falling_factorial(a, bvi->val_), a, bvi) {
        }
        void chain() {
          if (unlikely(boost::math::isnan(ad_)
                       || boost::math::isnan(bvi_->val_)))
            bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
          else
            bvi_->adj_ += adj_ * -boost::math::digamma(bvi_->val_ + 1);
        }
      };
    }

    inline var log_falling_factorial(const var& a,
                                     const double& b) {
      return var(new log_falling_factorial_vd_vari(a.vi_, b));
    }

    inline var log_falling_factorial(const var& a,
                                     const var& b) {
      return var(new log_falling_factorial_vv_vari(a.vi_, b.vi_));
    }

    inline var log_falling_factorial(const double& a,
                                     const var& b) {
      return var(new log_falling_factorial_dv_vari(a, b.vi_));
    }
  }
}
#endif
<|endoftext|>


<commit_before>// Copyright 2016 Frog Chen
//
// 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.
//=============================================================================
// ■ multiboot-info.cpp
//-----------------------------------------------------------------------------
//   处理与存储Multiboot启动信息结构，参照：
//   https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format
//=============================================================================

namespace MultibootInfo {
	uint32_t flags;
	uint32_t mem_lower, mem_upper;
	const char* cmdline;
	const char* boot_loader_name;
	void initialize(type_address address) {
		flags = Memory::read32_at(address);
		if (flags & 1 << 0) {
			mem_lower = Memory::read32_at(address + 4);
			mem_upper = Memory::read32_at(address + 8);
		}
		if (flags & 1 << 2) {
			cmdline = (const char*) Memory::read32_at(address + 16);
		} else {
			cmdline = nullptr;
		}
		if (flags & 1 << 9) {
			boot_loader_name = (const char*) Memory::read32_at(address + 64);
		} else {
			boot_loader_name = nullptr;
		}
	}
}
<commit_msg>修理Multiboot信息<commit_after>// Copyright 2016 Frog Chen
//
// 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.
//=============================================================================
// ■ multiboot-info.cpp
//-----------------------------------------------------------------------------
//   处理与存储Multiboot启动信息结构，参照：
//   https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format
//=============================================================================

namespace MultibootInfo {
	uint32_t flags;
	type_address mem_lower, mem_upper;
	const char* cmdline;
	const char* boot_loader_name;
	void initialize(type_address address) {
		flags = Memory::read32_at(address);
		if (flags & 1 << 0) {
			mem_lower = Memory::read32_at(address + 4);
			mem_upper = Memory::read32_at(address + 8);
		} else {
			mem_lower = mem_upper = 0;
		}
		if (flags & 1 << 2) {
			cmdline = (const char*) Memory::read32_at(address + 16);
		} else {
			cmdline = nullptr;
		}
		if (flags & 1 << 9) {
			boot_loader_name = (const char*) Memory::read32_at(address + 64);
		} else {
			boot_loader_name = nullptr;
		}
	}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: sdbcdriverenum.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-02-03 18:49:30 $
 *
 *  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 EXPRESS 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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _OFFMGR_SDBCDRIVERENUMERATION_HXX_
#define _OFFMGR_SDBCDRIVERENUMERATION_HXX_

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

namespace rtl
{
    class OUString;
}

//........................................................................
namespace offapp
{
//........................................................................

    //====================================================================
    //= ODriverEnumeration
    //====================================================================
    class ODriverEnumerationImpl;
    /** simple class for accessing SDBC drivers registered within the office

Rather small, introduced to not contaminate other instances with the
        exception handling (code-size-bloating) implementations here.

    */
    class ODriverEnumeration
    {
    private:
        ODriverEnumerationImpl* m_pImpl;

    public:
        ODriverEnumeration() throw();
        ~ODriverEnumeration() throw();

        typedef const   ::rtl::OUString*    const_iterator;

        const_iterator  begin() const throw();
        const_iterator  end() const throw();
        sal_Int32       size() const throw();
    };

//........................................................................
}   // namespace offapp
//........................................................................

#endif // _OFFMGR_SDBCDRIVERENUMERATION_HXX_

<commit_msg>INTEGRATION: CWS ooo20040704 (1.2.266); FILE MERGED 2004/06/28 14:24:06 cmc 1.2.266.1: #i30801# allow using system stl if possible<commit_after>/*************************************************************************
 *
 *  $RCSfile: sdbcdriverenum.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-09-08 14:40:01 $
 *
 *  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 EXPRESS 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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _OFFMGR_SDBCDRIVERENUMERATION_HXX_
#define _OFFMGR_SDBCDRIVERENUMERATION_HXX_

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#include <vector>

namespace rtl
{
    class OUString;
}

//........................................................................
namespace offapp
{
//........................................................................

    //====================================================================
    //= ODriverEnumeration
    //====================================================================
    class ODriverEnumerationImpl;
    /** simple class for accessing SDBC drivers registered within the office

Rather small, introduced to not contaminate other instances with the
        exception handling (code-size-bloating) implementations here.

    */
    class ODriverEnumeration
    {
    private:
        ODriverEnumerationImpl* m_pImpl;

    public:
        ODriverEnumeration() throw();
        ~ODriverEnumeration() throw();
        typedef ::std::vector< ::rtl::OUString >::const_iterator const_iterator;

        const_iterator  begin() const throw();
        const_iterator  end() const throw();
        sal_Int32 size() const throw();
    };

//........................................................................
}   // namespace offapp
//........................................................................

#endif // _OFFMGR_SDBCDRIVERENUMERATION_HXX_

<|endoftext|>


<commit_before>#include "Iop_Sysclib.h"

using namespace Iop;

CSysclib::CSysclib(uint8* ram, CStdio& stdio)
: m_ram(ram)
, m_stdio(stdio)
{

}

CSysclib::~CSysclib()
{

}

std::string CSysclib::GetId() const
{
	return "sysclib";
}

std::string CSysclib::GetFunctionName(unsigned int functionId) const
{
	switch(functionId)
	{
	case 6:
		return "toupper";
		break;
	case 7:
		return "tolower";
		break;
	case 8:
		return "look_ctype_table";
		break;
	case 11:
		return "memcmp";
		break;
	case 12:
		return "memcpy";
		break;
	case 14:
		return "memset";
		break;
	case 16:
		return "bcopy";
		break;
	case 17:
		return "bzero";
		break;
	case 19:
		return "sprintf";
		break;
	case 22:
		return "strcmp";
		break;
	case 23:
		return "strcpy";
		break;
	case 27:
		return "strlen";
		break;
	case 29:
		return "strncmp";
		break;
	case 32:
		return "strrchr";
		break;
	case 36:
		return "strtol";
		break;
	case 41:
		return "wmemset";
		break;
	default:
		return "unknown";
		break;
	}
}

void CSysclib::Invoke(CMIPS& context, unsigned int functionId)
{
	switch(functionId)
	{
	case 6:
		context.m_State.nGPR[CMIPS::V0].nD0 = toupper(
			context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 7:
		context.m_State.nGPR[CMIPS::V0].nD0 = tolower(
			context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 8:
		context.m_State.nGPR[CMIPS::V0].nD0 = __look_ctype_table(
			context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 11:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__memcmp(
			reinterpret_cast<void*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<void*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0]),
			context.m_State.nGPR[CMIPS::A2].nV0
			));
		break;
	case 12:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__memcpy(
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			&m_ram[context.m_State.nGPR[CMIPS::A1].nV0],
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 13:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__memmove(
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			&m_ram[context.m_State.nGPR[CMIPS::A1].nV0],
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 14:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__memset(
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			context.m_State.nGPR[CMIPS::A1].nV0,
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 16:
		//bcopy
		memmove(
			&m_ram[context.m_State.nGPR[CMIPS::A1].nV0],
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 17:
		//bzero
		__memset(
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			0,
			context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 19:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__sprintf(context));
		break;
	case 22:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__strcmp(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0])
			));
		break;
	case 23:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__strcpy(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0])
			);
		break;
	case 27:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__strlen(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0])
			));
		break;
	case 29:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__strncmp(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0]),
			context.m_State.nGPR[CMIPS::A2].nV0));
		break;
	case 30:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__strncpy(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0]),
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 32:
		context.m_State.nGPR[CMIPS::V0].nD0 = __strrchr(
			context.m_State.nGPR[CMIPS::A0].nV0,
			context.m_State.nGPR[CMIPS::A1].nV0
		);
		break;
	case 36:
		assert(context.m_State.nGPR[CMIPS::A1].nV0 == 0);
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__strtol(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			context.m_State.nGPR[CMIPS::A2].nV0
			));
		break;
	case 41:
		//wmemset
		{
			uint32* dest = reinterpret_cast<uint32*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]);
			uint32 value = context.m_State.nGPR[CMIPS::A1].nV0;
			uint32 numChars = context.m_State.nGPR[CMIPS::A2].nV0;
			uint32* end = dest + numChars;
			while(dest < end)
			{
				*dest++ = value;
			}
			context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nV0;
		}
		break;
	default:
		printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId);
		assert(0);
		break;
	}
}

uint32 CSysclib::__look_ctype_table(uint32 character)
{
	static const uint8 ctype_table[128] =
	{
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,

		0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
		0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
		0x04, 0x04, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,

		0x10, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x01,
		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x10, 0x10, 0x10, 0x10, 0x10,

		0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x02,
		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
		0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x20
	};

	assert(character < 128);

	return ctype_table[character & 0x7F];
}

uint32 CSysclib::__memcmp(const void* dst, const void* src, uint32 length)
{
	return static_cast<uint32>(memcmp(dst, src, length));
}

void CSysclib::__memcpy(void* dest, const void* src, unsigned int length)
{
	memcpy(dest, src, length);
}

void CSysclib::__memmove(void* dest, const void* src, uint32 length)
{
	memmove(dest, src, length);
}

void CSysclib::__memset(void* dest, int character, unsigned int length)
{
	memset(dest, character, length);
}

uint32 CSysclib::__sprintf(CMIPS& context)
{
	CArgumentIterator args(context);
	char* destination = reinterpret_cast<char*>(&m_ram[args.GetNext()]);
	std::string output = m_stdio.PrintFormatted(args);
	strcpy(destination, output.c_str());
	return static_cast<uint32>(output.length());
}

uint32 CSysclib::__strlen(const char* string)
{
	return static_cast<uint32>(strlen(string));
}

uint32 CSysclib::__strcmp(const char* s1, const char* s2)
{
	return static_cast<uint32>(strcmp(s1, s2));
}

void CSysclib::__strcpy(char* dst, const char* src)
{
	strcpy(dst, src);
}

uint32 CSysclib::__strncmp(const char* s1, const char* s2, uint32 length)
{
	return static_cast<uint32>(strncmp(s1, s2, length));
}

void CSysclib::__strncpy(char* dst, const char* src, unsigned int count)
{
	strncpy(dst, src, count);
}

uint32 CSysclib::__strrchr(uint32 strPtr, uint32 character)
{
	const char* str = reinterpret_cast<char*>(m_ram + strPtr);
	const char* result = strrchr(str, static_cast<int>(character));
	if(result == nullptr) return 0;
	size_t ptrDiff = result - str;
	return strPtr + ptrDiff;
}

uint32 CSysclib::__strtol(const char* string, unsigned int radix)
{
	return strtol(string, NULL, radix);
}
<commit_msg>Third parameter for wmemset is actually the number of bytes to be set.<commit_after>#include "Iop_Sysclib.h"

using namespace Iop;

CSysclib::CSysclib(uint8* ram, CStdio& stdio)
: m_ram(ram)
, m_stdio(stdio)
{

}

CSysclib::~CSysclib()
{

}

std::string CSysclib::GetId() const
{
	return "sysclib";
}

std::string CSysclib::GetFunctionName(unsigned int functionId) const
{
	switch(functionId)
	{
	case 6:
		return "toupper";
		break;
	case 7:
		return "tolower";
		break;
	case 8:
		return "look_ctype_table";
		break;
	case 11:
		return "memcmp";
		break;
	case 12:
		return "memcpy";
		break;
	case 14:
		return "memset";
		break;
	case 16:
		return "bcopy";
		break;
	case 17:
		return "bzero";
		break;
	case 19:
		return "sprintf";
		break;
	case 22:
		return "strcmp";
		break;
	case 23:
		return "strcpy";
		break;
	case 27:
		return "strlen";
		break;
	case 29:
		return "strncmp";
		break;
	case 32:
		return "strrchr";
		break;
	case 36:
		return "strtol";
		break;
	case 41:
		return "wmemset";
		break;
	default:
		return "unknown";
		break;
	}
}

void CSysclib::Invoke(CMIPS& context, unsigned int functionId)
{
	switch(functionId)
	{
	case 6:
		context.m_State.nGPR[CMIPS::V0].nD0 = toupper(
			context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 7:
		context.m_State.nGPR[CMIPS::V0].nD0 = tolower(
			context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 8:
		context.m_State.nGPR[CMIPS::V0].nD0 = __look_ctype_table(
			context.m_State.nGPR[CMIPS::A0].nV0);
		break;
	case 11:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__memcmp(
			reinterpret_cast<void*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<void*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0]),
			context.m_State.nGPR[CMIPS::A2].nV0
			));
		break;
	case 12:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__memcpy(
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			&m_ram[context.m_State.nGPR[CMIPS::A1].nV0],
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 13:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__memmove(
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			&m_ram[context.m_State.nGPR[CMIPS::A1].nV0],
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 14:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__memset(
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			context.m_State.nGPR[CMIPS::A1].nV0,
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 16:
		//bcopy
		memmove(
			&m_ram[context.m_State.nGPR[CMIPS::A1].nV0],
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 17:
		//bzero
		__memset(
			&m_ram[context.m_State.nGPR[CMIPS::A0].nV0],
			0,
			context.m_State.nGPR[CMIPS::A1].nV0);
		break;
	case 19:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__sprintf(context));
		break;
	case 22:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__strcmp(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0])
			));
		break;
	case 23:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__strcpy(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0])
			);
		break;
	case 27:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__strlen(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0])
			));
		break;
	case 29:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__strncmp(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0]),
			context.m_State.nGPR[CMIPS::A2].nV0));
		break;
	case 30:
		context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0;
		__strncpy(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0]),
			context.m_State.nGPR[CMIPS::A2].nV0);
		break;
	case 32:
		context.m_State.nGPR[CMIPS::V0].nD0 = __strrchr(
			context.m_State.nGPR[CMIPS::A0].nV0,
			context.m_State.nGPR[CMIPS::A1].nV0
		);
		break;
	case 36:
		assert(context.m_State.nGPR[CMIPS::A1].nV0 == 0);
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(__strtol(
			reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			context.m_State.nGPR[CMIPS::A2].nV0
			));
		break;
	case 41:
		//wmemset
		{
			uint32* dest = reinterpret_cast<uint32*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]);
			uint32 value = context.m_State.nGPR[CMIPS::A1].nV0;
			uint32 numBytes = context.m_State.nGPR[CMIPS::A2].nV0;
			uint32* end = dest + (numBytes / 4);
			while(dest < end)
			{
				*dest++ = value;
			}
			context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nV0;
		}
		break;
	default:
		printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId);
		assert(0);
		break;
	}
}

uint32 CSysclib::__look_ctype_table(uint32 character)
{
	static const uint8 ctype_table[128] =
	{
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,

		0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
		0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
		0x04, 0x04, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,

		0x10, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x01,
		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x10, 0x10, 0x10, 0x10, 0x10,

		0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x02,
		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
		0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x20
	};

	assert(character < 128);

	return ctype_table[character & 0x7F];
}

uint32 CSysclib::__memcmp(const void* dst, const void* src, uint32 length)
{
	return static_cast<uint32>(memcmp(dst, src, length));
}

void CSysclib::__memcpy(void* dest, const void* src, unsigned int length)
{
	memcpy(dest, src, length);
}

void CSysclib::__memmove(void* dest, const void* src, uint32 length)
{
	memmove(dest, src, length);
}

void CSysclib::__memset(void* dest, int character, unsigned int length)
{
	memset(dest, character, length);
}

uint32 CSysclib::__sprintf(CMIPS& context)
{
	CArgumentIterator args(context);
	char* destination = reinterpret_cast<char*>(&m_ram[args.GetNext()]);
	std::string output = m_stdio.PrintFormatted(args);
	strcpy(destination, output.c_str());
	return static_cast<uint32>(output.length());
}

uint32 CSysclib::__strlen(const char* string)
{
	return static_cast<uint32>(strlen(string));
}

uint32 CSysclib::__strcmp(const char* s1, const char* s2)
{
	return static_cast<uint32>(strcmp(s1, s2));
}

void CSysclib::__strcpy(char* dst, const char* src)
{
	strcpy(dst, src);
}

uint32 CSysclib::__strncmp(const char* s1, const char* s2, uint32 length)
{
	return static_cast<uint32>(strncmp(s1, s2, length));
}

void CSysclib::__strncpy(char* dst, const char* src, unsigned int count)
{
	strncpy(dst, src, count);
}

uint32 CSysclib::__strrchr(uint32 strPtr, uint32 character)
{
	const char* str = reinterpret_cast<char*>(m_ram + strPtr);
	const char* result = strrchr(str, static_cast<int>(character));
	if(result == nullptr) return 0;
	size_t ptrDiff = result - str;
	return strPtr + ptrDiff;
}

uint32 CSysclib::__strtol(const char* string, unsigned int radix)
{
	return strtol(string, NULL, radix);
}
<|endoftext|>


<commit_before>/*
* DataSource
* (C) 1999-2007 Jack Lloyd
*     2005 Matthew Gregan
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/data_src.h>
#include <botan/exceptn.h>
#include <algorithm>

#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
  #include <fstream>
#endif

namespace Botan {

/*
* Read a single byte from the DataSource
*/
size_t DataSource::read_byte(uint8_t& out)
   {
   return read(&out, 1);
   }

/*
* Peek a single byte from the DataSource
*/
size_t DataSource::peek_byte(uint8_t& out) const
   {
   return peek(&out, 1, 0);
   }

/*
* Discard the next N bytes of the data
*/
size_t DataSource::discard_next(size_t n)
   {
   uint8_t buf[64] = { 0 };
   size_t discarded = 0;

   while(n)
      {
      const size_t got = this->read(buf, std::min(n, sizeof(buf)));
      discarded += got;
      n -= got;

      if(got == 0)
         break;
      }

   return discarded;
   }

/*
* Read from a memory buffer
*/
size_t DataSource_Memory::read(uint8_t out[], size_t length)
   {
   size_t got = std::min<size_t>(m_source.size() - m_offset, length);
   copy_mem(out, m_source.data() + m_offset, got);
   m_offset += got;
   return got;
   }

bool DataSource_Memory::check_available(size_t n)
   {
   return (n <= (m_source.size() - m_offset));
   }

/*
* Peek into a memory buffer
*/
size_t DataSource_Memory::peek(uint8_t out[], size_t length,
                               size_t peek_offset) const
   {
   const size_t bytes_left = m_source.size() - m_offset;
   if(peek_offset >= bytes_left) return 0;

   size_t got = std::min(bytes_left - peek_offset, length);
   copy_mem(out, &m_source[m_offset + peek_offset], got);
   return got;
   }

/*
* Check if the memory buffer is empty
*/
bool DataSource_Memory::end_of_data() const
   {
   return (m_offset == m_source.size());
   }

/*
* DataSource_Memory Constructor
*/
DataSource_Memory::DataSource_Memory(const std::string& in) :
   m_source(cast_char_ptr_to_uint8(in.data()),
            cast_char_ptr_to_uint8(in.data()) + in.length()),
   m_offset(0)
   {
   }

/*
* Read from a stream
*/
size_t DataSource_Stream::read(uint8_t out[], size_t length)
   {
   m_source.read(cast_uint8_ptr_to_char(out), length);
   if(m_source.bad())
      throw Stream_IO_Error("DataSource_Stream::read: Source failure");

   const size_t got = static_cast<size_t>(m_source.gcount());
   m_total_read += got;
   return got;
   }

bool DataSource_Stream::check_available(size_t n)
   {
   const std::streampos orig_pos = m_source.tellg();
   m_source.seekg(0, std::ios::end);
   const size_t avail = static_cast<size_t>(m_source.tellg() - orig_pos);
   m_source.seekg(orig_pos);
   return (avail >= n);
   }

/*
* Peek into a stream
*/
size_t DataSource_Stream::peek(uint8_t out[], size_t length, size_t offset) const
   {
   if(end_of_data())
      throw Invalid_State("DataSource_Stream: Cannot peek when out of data");

   size_t got = 0;

   if(offset)
      {
      secure_vector<uint8_t> buf(offset);
      m_source.read(cast_uint8_ptr_to_char(buf.data()), buf.size());
      if(m_source.bad())
         throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
      got = static_cast<size_t>(m_source.gcount());
      }

   if(got == offset)
      {
      m_source.read(cast_uint8_ptr_to_char(out), length);
      if(m_source.bad())
         throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
      got = static_cast<size_t>(m_source.gcount());
      }

   if(m_source.eof())
      m_source.clear();
   m_source.seekg(m_total_read, std::ios::beg);

   return got;
   }

/*
* Check if the stream is empty or in error
*/
bool DataSource_Stream::end_of_data() const
   {
   return (!m_source.good());
   }

/*
* Return a human-readable ID for this stream
*/
std::string DataSource_Stream::id() const
   {
   return m_identifier;
   }

#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)

/*
* DataSource_Stream Constructor
*/
DataSource_Stream::DataSource_Stream(const std::string& path,
                                     bool use_binary) :
   m_identifier(path),
   m_source_memory(new std::ifstream(path, use_binary ? std::ios::binary : std::ios::in)),
   m_source(*m_source_memory),
   m_total_read(0)
   {
   if(!m_source.good())
      {
      throw Stream_IO_Error("DataSource: Failure opening file " + path);
      }
   }

#endif

/*
* DataSource_Stream Constructor
*/
DataSource_Stream::DataSource_Stream(std::istream& in,
                                     const std::string& name) :
   m_identifier(name),
   m_source(in),
   m_total_read(0)
   {
   }

DataSource_Stream::~DataSource_Stream()
   {
   // for ~unique_ptr
   }

}
<commit_msg>Add missing include<commit_after>/*
* DataSource
* (C) 1999-2007 Jack Lloyd
*     2005 Matthew Gregan
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/data_src.h>
#include <botan/exceptn.h>
#include <algorithm>
#include <istream>

#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
  #include <fstream>
#endif

namespace Botan {

/*
* Read a single byte from the DataSource
*/
size_t DataSource::read_byte(uint8_t& out)
   {
   return read(&out, 1);
   }

/*
* Peek a single byte from the DataSource
*/
size_t DataSource::peek_byte(uint8_t& out) const
   {
   return peek(&out, 1, 0);
   }

/*
* Discard the next N bytes of the data
*/
size_t DataSource::discard_next(size_t n)
   {
   uint8_t buf[64] = { 0 };
   size_t discarded = 0;

   while(n)
      {
      const size_t got = this->read(buf, std::min(n, sizeof(buf)));
      discarded += got;
      n -= got;

      if(got == 0)
         break;
      }

   return discarded;
   }

/*
* Read from a memory buffer
*/
size_t DataSource_Memory::read(uint8_t out[], size_t length)
   {
   size_t got = std::min<size_t>(m_source.size() - m_offset, length);
   copy_mem(out, m_source.data() + m_offset, got);
   m_offset += got;
   return got;
   }

bool DataSource_Memory::check_available(size_t n)
   {
   return (n <= (m_source.size() - m_offset));
   }

/*
* Peek into a memory buffer
*/
size_t DataSource_Memory::peek(uint8_t out[], size_t length,
                               size_t peek_offset) const
   {
   const size_t bytes_left = m_source.size() - m_offset;
   if(peek_offset >= bytes_left) return 0;

   size_t got = std::min(bytes_left - peek_offset, length);
   copy_mem(out, &m_source[m_offset + peek_offset], got);
   return got;
   }

/*
* Check if the memory buffer is empty
*/
bool DataSource_Memory::end_of_data() const
   {
   return (m_offset == m_source.size());
   }

/*
* DataSource_Memory Constructor
*/
DataSource_Memory::DataSource_Memory(const std::string& in) :
   m_source(cast_char_ptr_to_uint8(in.data()),
            cast_char_ptr_to_uint8(in.data()) + in.length()),
   m_offset(0)
   {
   }

/*
* Read from a stream
*/
size_t DataSource_Stream::read(uint8_t out[], size_t length)
   {
   m_source.read(cast_uint8_ptr_to_char(out), length);
   if(m_source.bad())
      throw Stream_IO_Error("DataSource_Stream::read: Source failure");

   const size_t got = static_cast<size_t>(m_source.gcount());
   m_total_read += got;
   return got;
   }

bool DataSource_Stream::check_available(size_t n)
   {
   const std::streampos orig_pos = m_source.tellg();
   m_source.seekg(0, std::ios::end);
   const size_t avail = static_cast<size_t>(m_source.tellg() - orig_pos);
   m_source.seekg(orig_pos);
   return (avail >= n);
   }

/*
* Peek into a stream
*/
size_t DataSource_Stream::peek(uint8_t out[], size_t length, size_t offset) const
   {
   if(end_of_data())
      throw Invalid_State("DataSource_Stream: Cannot peek when out of data");

   size_t got = 0;

   if(offset)
      {
      secure_vector<uint8_t> buf(offset);
      m_source.read(cast_uint8_ptr_to_char(buf.data()), buf.size());
      if(m_source.bad())
         throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
      got = static_cast<size_t>(m_source.gcount());
      }

   if(got == offset)
      {
      m_source.read(cast_uint8_ptr_to_char(out), length);
      if(m_source.bad())
         throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
      got = static_cast<size_t>(m_source.gcount());
      }

   if(m_source.eof())
      m_source.clear();
   m_source.seekg(m_total_read, std::ios::beg);

   return got;
   }

/*
* Check if the stream is empty or in error
*/
bool DataSource_Stream::end_of_data() const
   {
   return (!m_source.good());
   }

/*
* Return a human-readable ID for this stream
*/
std::string DataSource_Stream::id() const
   {
   return m_identifier;
   }

#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)

/*
* DataSource_Stream Constructor
*/
DataSource_Stream::DataSource_Stream(const std::string& path,
                                     bool use_binary) :
   m_identifier(path),
   m_source_memory(new std::ifstream(path, use_binary ? std::ios::binary : std::ios::in)),
   m_source(*m_source_memory),
   m_total_read(0)
   {
   if(!m_source.good())
      {
      throw Stream_IO_Error("DataSource: Failure opening file " + path);
      }
   }

#endif

/*
* DataSource_Stream Constructor
*/
DataSource_Stream::DataSource_Stream(std::istream& in,
                                     const std::string& name) :
   m_identifier(name),
   m_source(in),
   m_total_read(0)
   {
   }

DataSource_Stream::~DataSource_Stream()
   {
   // for ~unique_ptr
   }

}
<|endoftext|>


<commit_before>///
/// @file  S2_trivial.cpp
/// @brief Calculate the contribution of the trivial special leaves
///        in parallel using OpenMP.
///
/// Copyright (C) 2016 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <PiTable.hpp>
#include <primecount.hpp>
#include <primecount-internal.hpp>
#include <primesieve.hpp>
#include <generate.hpp>
#include <int128_t.hpp>

#include <stdint.h>
#include <algorithm>
#include <vector>

#ifdef _OPENMP
  #include <omp.h>
#endif

using namespace std;
using namespace primecount;

namespace {

template <typename T>
T S2_trivial_OpenMP(T x,
                    int64_t y,
                    int64_t z,
                    int64_t c,
                    int threads)
{
  int64_t thread_threshold = ipow(10, 7);
  threads = ideal_num_threads(threads, y, thread_threshold);

  PiTable pi(y);
  int64_t pi_y = pi[y];
  int64_t sqrtz = isqrt(z);
  int64_t prime_c = nth_prime(c);

  T s2_trivial = 0;

  // Find all trivial leaves: n = primes[b] * primes[l]
  // which satisfy phi(x / n), b - 1) = 1
  #pragma omp parallel for num_threads(threads) reduction(+: s2_trivial)
  for (int64_t i = 0; i < threads; i++)
  {
    int64_t start = max(prime_c, sqrtz) + 1;
    int64_t thread_distance = ceil_div(y - start, threads);
    start += thread_distance * i;
    int64_t stop = min(start + thread_distance, y);
    primesieve::iterator it(start - 1, stop);
    T prime;

    while ((prime = it.next_prime()) < stop)
    {
      int64_t xn = (int64_t) max(x / (prime * prime), prime);
      s2_trivial += pi_y - pi[xn];
    }
  }

  return s2_trivial;
}

} // namespace

namespace primecount {

int64_t S2_trivial(int64_t x,
                   int64_t y,
                   int64_t z,
                   int64_t c,
                   int threads)
{
  print("");
  print("=== S2_trivial(x, y) ===");
  print("Computation of the trivial special leaves");
  print(x, y, c, threads);

  double time = get_wtime();
  int64_t s2_trivial = S2_trivial_OpenMP(x, y, z, c, threads);

  print("S2_trivial", s2_trivial, time);
  return s2_trivial;
}

#ifdef HAVE_INT128_T

int128_t S2_trivial(int128_t x,
                    int64_t y,
                    int64_t z,
                    int64_t c,
                    int threads)
{
  print("");
  print("=== S2_trivial(x, y) ===");
  print("Computation of the trivial special leaves");
  print(x, y, c, threads);

  double time = get_wtime();
  int128_t s2_trivial = S2_trivial_OpenMP(x, y, z, c, threads);

  print("S2_trivial", s2_trivial, time);
  return s2_trivial;
}

#endif

} // namespace
<commit_msg>Remove unused headers<commit_after>///
/// @file  S2_trivial.cpp
/// @brief Calculate the contribution of the trivial special leaves
///        in parallel using OpenMP.
///
/// Copyright (C) 2018 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <PiTable.hpp>
#include <primecount.hpp>
#include <primecount-internal.hpp>
#include <primesieve.hpp>
#include <int128_t.hpp>

#include <stdint.h>
#include <algorithm>

#ifdef _OPENMP
  #include <omp.h>
#endif

using namespace std;
using namespace primecount;

namespace {

template <typename T>
T S2_trivial_OpenMP(T x,
                    int64_t y,
                    int64_t z,
                    int64_t c,
                    int threads)
{
  int64_t thread_threshold = ipow(10, 7);
  threads = ideal_num_threads(threads, y, thread_threshold);

  PiTable pi(y);
  int64_t pi_y = pi[y];
  int64_t sqrtz = isqrt(z);
  int64_t prime_c = nth_prime(c);

  T s2_trivial = 0;

  // Find all trivial leaves: n = primes[b] * primes[l]
  // which satisfy phi(x / n), b - 1) = 1
  #pragma omp parallel for num_threads(threads) reduction(+: s2_trivial)
  for (int64_t i = 0; i < threads; i++)
  {
    int64_t start = max(prime_c, sqrtz) + 1;
    int64_t thread_distance = ceil_div(y - start, threads);
    start += thread_distance * i;
    int64_t stop = min(start + thread_distance, y);
    primesieve::iterator it(start - 1, stop);
    T prime;

    while ((prime = it.next_prime()) < stop)
    {
      int64_t xn = (int64_t) max(x / (prime * prime), prime);
      s2_trivial += pi_y - pi[xn];
    }
  }

  return s2_trivial;
}

} // namespace

namespace primecount {

int64_t S2_trivial(int64_t x,
                   int64_t y,
                   int64_t z,
                   int64_t c,
                   int threads)
{
  print("");
  print("=== S2_trivial(x, y) ===");
  print("Computation of the trivial special leaves");
  print(x, y, c, threads);

  double time = get_wtime();
  int64_t s2_trivial = S2_trivial_OpenMP(x, y, z, c, threads);

  print("S2_trivial", s2_trivial, time);
  return s2_trivial;
}

#ifdef HAVE_INT128_T

int128_t S2_trivial(int128_t x,
                    int64_t y,
                    int64_t z,
                    int64_t c,
                    int threads)
{
  print("");
  print("=== S2_trivial(x, y) ===");
  print("Computation of the trivial special leaves");
  print(x, y, c, threads);

  double time = get_wtime();
  int128_t s2_trivial = S2_trivial_OpenMP(x, y, z, c, threads);

  print("S2_trivial", s2_trivial, time);
  return s2_trivial;
}

#endif

} // namespace
<|endoftext|>


<commit_before>
#include "Stk.h"
extern "C" void test_func() {
    printf("Setting STK sample rate\n");
    stk::Stk::setSampleRate(44100);
}
<commit_msg>Fix warning.<commit_after>
#include "STK.h"
extern "C" void test_func() {
    printf("Setting STK sample rate\n");
    stk::Stk::setSampleRate(44100);
}
<|endoftext|>