<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/video_coding/codecs/i420/main/interface/i420.h"

#include <string.h>

#include "common_video/libyuv/include/webrtc_libyuv.h"

namespace webrtc
{

I420Encoder::I420Encoder():
_inited(false),
_encodedImage(),
_encodedCompleteCallback(NULL)
{}

I420Encoder::~I420Encoder() {
  _inited = false;
  if (_encodedImage._buffer != NULL) {
    delete [] _encodedImage._buffer;
    _encodedImage._buffer = NULL;
  }
}

int I420Encoder::Release() {
  // Should allocate an encoded frame and then release it here, for that we
  // actually need an init flag.
  if (_encodedImage._buffer != NULL) {
    delete [] _encodedImage._buffer;
    _encodedImage._buffer = NULL;
  }
  _inited = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

int I420Encoder::InitEncode(const VideoCodec* codecSettings,
                            int /*numberOfCores*/,
                            uint32_t /*maxPayloadSize */) {
  if (codecSettings == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (codecSettings->width < 1 || codecSettings->height < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }

  // Allocating encoded memory.
  if (_encodedImage._buffer != NULL) {
    delete [] _encodedImage._buffer;
    _encodedImage._buffer = NULL;
    _encodedImage._size = 0;
  }
  const uint32_t newSize = CalcBufferSize(kI420,
                                          codecSettings->width,
                                          codecSettings->height);
  uint8_t* newBuffer = new uint8_t[newSize];
  if (newBuffer == NULL) {
    return WEBRTC_VIDEO_CODEC_MEMORY;
  }
  _encodedImage._size = newSize;
  _encodedImage._buffer = newBuffer;

  // If no memory allocation, no point to init.
  _inited = true;
  return WEBRTC_VIDEO_CODEC_OK;
}

int I420Encoder::Encode(const I420VideoFrame& inputImage,
                        const CodecSpecificInfo* /*codecSpecificInfo*/,
                        const std::vector<VideoFrameType>* /*frame_types*/) {
  if (!_inited) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (_encodedCompleteCallback == NULL) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }

  _encodedImage._frameType = kKeyFrame; // No coding.
  _encodedImage._timeStamp = inputImage.timestamp();
  _encodedImage._encodedHeight = inputImage.height();
  _encodedImage._encodedWidth = inputImage.width();

  int req_length = CalcBufferSize(kI420, inputImage.width(),
                                  inputImage.height());
  if (_encodedImage._size > static_cast<unsigned int>(req_length)) {
    // Allocating encoded memory.
    if (_encodedImage._buffer != NULL) {
      delete [] _encodedImage._buffer;
      _encodedImage._buffer = NULL;
      _encodedImage._size = 0;
    }
    uint8_t* newBuffer = new uint8_t[req_length];
    if (newBuffer == NULL) {
      return WEBRTC_VIDEO_CODEC_MEMORY;
    }
    _encodedImage._size = req_length;
    _encodedImage._buffer = newBuffer;
  }

  int ret_length = ExtractBuffer(inputImage, req_length, _encodedImage._buffer);
  if (ret_length < 0)
    return WEBRTC_VIDEO_CODEC_MEMORY;
  _encodedImage._length = ret_length;

  _encodedCompleteCallback->Encoded(_encodedImage);
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Encoder::RegisterEncodeCompleteCallback(EncodedImageCallback* callback) {
  _encodedCompleteCallback = callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

I420Decoder::I420Decoder():
_decodedImage(),
_width(0),
_height(0),
_inited(false),
_decodeCompleteCallback(NULL)
{}

I420Decoder::~I420Decoder() {
  Release();
}

int
I420Decoder::Reset() {
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Decoder::InitDecode(const VideoCodec* codecSettings,
                        int /*numberOfCores */) {
  if (codecSettings == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  } else if (codecSettings->width < 1 || codecSettings->height < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  _width = codecSettings->width;
  _height = codecSettings->height;
  _inited = true;
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Decoder::Decode(const EncodedImage& inputImage,
                    bool /*missingFrames*/,
                    const RTPFragmentationHeader* /*fragmentation*/,
                    const CodecSpecificInfo* /*codecSpecificInfo*/,
                    int64_t /*renderTimeMs*/) {
  if (inputImage._buffer == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (_decodeCompleteCallback == NULL) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (inputImage._length <= 0) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (!_inited) {
   return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }

  // Set decoded image parameters.
  int half_width = (_width + 1) / 2;
  int half_height = (_height + 1) / 2;
  int size_y = _width * _height;
  int size_uv = half_width * half_height;

  const uint8_t* buffer_y = inputImage._buffer;
  const uint8_t* buffer_u = buffer_y + size_y;
  const uint8_t* buffer_v = buffer_u + size_uv;
  // TODO(mikhal): Do we need an align stride?
  int ret = _decodedImage.CreateFrame(size_y, buffer_y,
                                      size_uv, buffer_u,
                                      size_uv, buffer_v,
                                      _width, _height,
                                      _width, half_width, half_width);
  if (ret < 0) {
    return WEBRTC_VIDEO_CODEC_MEMORY;
  }
  _decodedImage.set_timestamp(inputImage._timeStamp);

  _decodeCompleteCallback->Decoded(_decodedImage);
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Decoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback) {
  _decodeCompleteCallback = callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Decoder::Release() {
  _inited = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

}
<commit_msg>i420:verify image length<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/video_coding/codecs/i420/main/interface/i420.h"

#include <string.h>

#include "common_video/libyuv/include/webrtc_libyuv.h"

namespace webrtc
{

I420Encoder::I420Encoder():
_inited(false),
_encodedImage(),
_encodedCompleteCallback(NULL)
{}

I420Encoder::~I420Encoder() {
  _inited = false;
  if (_encodedImage._buffer != NULL) {
    delete [] _encodedImage._buffer;
    _encodedImage._buffer = NULL;
  }
}

int I420Encoder::Release() {
  // Should allocate an encoded frame and then release it here, for that we
  // actually need an init flag.
  if (_encodedImage._buffer != NULL) {
    delete [] _encodedImage._buffer;
    _encodedImage._buffer = NULL;
  }
  _inited = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

int I420Encoder::InitEncode(const VideoCodec* codecSettings,
                            int /*numberOfCores*/,
                            uint32_t /*maxPayloadSize */) {
  if (codecSettings == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (codecSettings->width < 1 || codecSettings->height < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }

  // Allocating encoded memory.
  if (_encodedImage._buffer != NULL) {
    delete [] _encodedImage._buffer;
    _encodedImage._buffer = NULL;
    _encodedImage._size = 0;
  }
  const uint32_t newSize = CalcBufferSize(kI420,
                                          codecSettings->width,
                                          codecSettings->height);
  uint8_t* newBuffer = new uint8_t[newSize];
  if (newBuffer == NULL) {
    return WEBRTC_VIDEO_CODEC_MEMORY;
  }
  _encodedImage._size = newSize;
  _encodedImage._buffer = newBuffer;

  // If no memory allocation, no point to init.
  _inited = true;
  return WEBRTC_VIDEO_CODEC_OK;
}

int I420Encoder::Encode(const I420VideoFrame& inputImage,
                        const CodecSpecificInfo* /*codecSpecificInfo*/,
                        const std::vector<VideoFrameType>* /*frame_types*/) {
  if (!_inited) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (_encodedCompleteCallback == NULL) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }

  _encodedImage._frameType = kKeyFrame; // No coding.
  _encodedImage._timeStamp = inputImage.timestamp();
  _encodedImage._encodedHeight = inputImage.height();
  _encodedImage._encodedWidth = inputImage.width();

  int req_length = CalcBufferSize(kI420, inputImage.width(),
                                  inputImage.height());
  if (_encodedImage._size > static_cast<unsigned int>(req_length)) {
    // Allocating encoded memory.
    if (_encodedImage._buffer != NULL) {
      delete [] _encodedImage._buffer;
      _encodedImage._buffer = NULL;
      _encodedImage._size = 0;
    }
    uint8_t* newBuffer = new uint8_t[req_length];
    if (newBuffer == NULL) {
      return WEBRTC_VIDEO_CODEC_MEMORY;
    }
    _encodedImage._size = req_length;
    _encodedImage._buffer = newBuffer;
  }

  int ret_length = ExtractBuffer(inputImage, req_length, _encodedImage._buffer);
  if (ret_length < 0)
    return WEBRTC_VIDEO_CODEC_MEMORY;
  _encodedImage._length = ret_length;

  _encodedCompleteCallback->Encoded(_encodedImage);
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Encoder::RegisterEncodeCompleteCallback(EncodedImageCallback* callback) {
  _encodedCompleteCallback = callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

I420Decoder::I420Decoder():
_decodedImage(),
_width(0),
_height(0),
_inited(false),
_decodeCompleteCallback(NULL)
{}

I420Decoder::~I420Decoder() {
  Release();
}

int
I420Decoder::Reset() {
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Decoder::InitDecode(const VideoCodec* codecSettings,
                        int /*numberOfCores */) {
  if (codecSettings == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  } else if (codecSettings->width < 1 || codecSettings->height < 1) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  _width = codecSettings->width;
  _height = codecSettings->height;
  _inited = true;
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Decoder::Decode(const EncodedImage& inputImage,
                    bool /*missingFrames*/,
                    const RTPFragmentationHeader* /*fragmentation*/,
                    const CodecSpecificInfo* /*codecSpecificInfo*/,
                    int64_t /*renderTimeMs*/) {
  if (inputImage._buffer == NULL) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (_decodeCompleteCallback == NULL) {
    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }
  if (inputImage._length <= 0) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (inputImage._completeFrame == false) {
    return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
  }
  if (!_inited) {
   return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
  }

  // Verify that the available length is sufficient:
  int req_length = CalcBufferSize(kI420, _width, _height);
  if (req_length > static_cast<int>(inputImage._length)) {
    return WEBRTC_VIDEO_CODEC_ERROR;
  }
  // Set decoded image parameters.
  int half_width = (_width + 1) / 2;
  int half_height = (_height + 1) / 2;
  int size_y = _width * _height;
  int size_uv = half_width * half_height;

  const uint8_t* buffer_y = inputImage._buffer;
  const uint8_t* buffer_u = buffer_y + size_y;
  const uint8_t* buffer_v = buffer_u + size_uv;
  // TODO(mikhal): Do we need an align stride?
  int ret = _decodedImage.CreateFrame(size_y, buffer_y,
                                      size_uv, buffer_u,
                                      size_uv, buffer_v,
                                      _width, _height,
                                      _width, half_width, half_width);
  if (ret < 0) {
    return WEBRTC_VIDEO_CODEC_MEMORY;
  }
  _decodedImage.set_timestamp(inputImage._timeStamp);

  _decodeCompleteCallback->Decoded(_decodedImage);
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Decoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback) {
  _decodeCompleteCallback = callback;
  return WEBRTC_VIDEO_CODEC_OK;
}

int
I420Decoder::Release() {
  _inited = false;
  return WEBRTC_VIDEO_CODEC_OK;
}

}
<|endoftext|>


<commit_before>//===-- lldb.cpp ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-private.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

#include "llvm/ADT/StringRef.h"

#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVM.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h"
#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h"
#include "Plugins/Platform/Linux/PlatformLinux.h"
#if defined (__APPLE__)
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
#include "Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.h"
#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
#include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
#endif

#include "Plugins/Process/mach-core/ProcessMachCore.h"

#if defined (__linux__)
#include "Plugins/Process/Linux/ProcessLinux.h"
#endif

#if defined (__FreeBSD__)
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Process/POSIX/ProcessPOSIX.h"
#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
#endif

#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"

using namespace lldb;
using namespace lldb_private;

void
lldb_private::Initialize ()
{
    // Make sure we inialize only once
    static Mutex g_inited_mutex(Mutex::eMutexTypeRecursive);
    static bool g_inited = false;

    Mutex::Locker locker(g_inited_mutex);
    if (!g_inited)
    {
        g_inited = true;
        Log::Initialize();
        Timer::Initialize ();
        Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

        ABIMacOSX_i386::Initialize();
        ABIMacOSX_arm::Initialize();
        ABISysV_x86_64::Initialize();
        DisassemblerLLVMC::Initialize();
        DisassemblerLLVM::Initialize();
        ObjectContainerBSDArchive::Initialize();
        ObjectFileELF::Initialize();
        SymbolFileDWARF::Initialize();
        SymbolFileSymtab::Initialize();
        UnwindAssemblyInstEmulation::Initialize();
        UnwindAssembly_x86::Initialize();
        EmulateInstructionARM::Initialize ();
        ObjectFilePECOFF::Initialize ();
        DynamicLoaderPOSIXDYLD::Initialize ();
        PlatformFreeBSD::Initialize();
        PlatformLinux::Initialize();
#if defined (__APPLE__)
        //----------------------------------------------------------------------
        // Apple/Darwin hosted plugins
        //----------------------------------------------------------------------
        DynamicLoaderMacOSXDYLD::Initialize();
        DynamicLoaderDarwinKernel::Initialize();
        OperatingSystemDarwinKernel::Initialize();
        SymbolFileDWARFDebugMap::Initialize();
        ItaniumABILanguageRuntime::Initialize();
        AppleObjCRuntimeV2::Initialize();
        AppleObjCRuntimeV1::Initialize();
        ObjectContainerUniversalMachO::Initialize();
        ObjectFileMachO::Initialize();
        ProcessKDP::Initialize();
        ProcessGDBRemote::Initialize();
        ProcessMachCore::Initialize();
        SymbolVendorMacOSX::Initialize();
        PlatformRemoteiOS::Initialize();
        PlatformMacOSX::Initialize();
        PlatformiOSSimulator::Initialize();
#endif
#if defined (__linux__)
        //----------------------------------------------------------------------
        // Linux hosted plugins
        //----------------------------------------------------------------------
        ProcessLinux::Initialize();
#endif
#if defined (__FreeBSD__)
        ProcessFreeBSD::Initialize();
        ProcessGDBRemote::Initialize();
#endif
        //----------------------------------------------------------------------
        // Platform agnostic plugins
        //----------------------------------------------------------------------
        PlatformRemoteGDBServer::Initialize ();
        DynamicLoaderStatic::Initialize();

        // Scan for any system or user LLDB plug-ins
        PluginManager::Initialize();

        // The process settings need to know about installed plug-ins, so the Settings must be initialized
        // AFTER PluginManager::Initialize is called.

        Debugger::SettingsInitialize();
    }
}

void
lldb_private::WillTerminate()
{
    Host::WillTerminate();
}

void
lldb_private::Terminate ()
{
    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

    // Terminate and unload and loaded system or user LLDB plug-ins
    PluginManager::Terminate();

    ABIMacOSX_i386::Terminate();
    ABIMacOSX_arm::Terminate();
    ABISysV_x86_64::Terminate();
    DisassemblerLLVMC::Terminate();
    DisassemblerLLVM::Terminate();
    ObjectContainerBSDArchive::Terminate();
    ObjectFileELF::Terminate();
    SymbolFileDWARF::Terminate();
    SymbolFileSymtab::Terminate();
    UnwindAssembly_x86::Terminate();
    UnwindAssemblyInstEmulation::Terminate();
    EmulateInstructionARM::Terminate ();
    ObjectFilePECOFF::Terminate ();
    DynamicLoaderPOSIXDYLD::Terminate ();
    PlatformFreeBSD::Terminate();
    PlatformLinux::Terminate();
#if defined (__APPLE__)
    DynamicLoaderMacOSXDYLD::Terminate();
    DynamicLoaderDarwinKernel::Terminate();
    OperatingSystemDarwinKernel::Terminate();
    SymbolFileDWARFDebugMap::Terminate();
    ItaniumABILanguageRuntime::Terminate();
    AppleObjCRuntimeV2::Terminate();
    AppleObjCRuntimeV1::Terminate();
    ObjectContainerUniversalMachO::Terminate();
    ObjectFileMachO::Terminate();
    ProcessMachCore::Terminate();
    ProcessKDP::Terminate();
    ProcessGDBRemote::Terminate();
    SymbolVendorMacOSX::Terminate();
    PlatformMacOSX::Terminate();
    PlatformRemoteiOS::Terminate();
    PlatformiOSSimulator::Terminate();
#endif

    Debugger::SettingsTerminate ();

#if defined (__linux__)
    ProcessLinux::Terminate();
#endif

#if defined (__FreeBSD__)
    ProcessFreeBSD::Terminate();
    ProcessGDBRemote::Terminate();
#endif

    DynamicLoaderStatic::Terminate();

    Log::Terminate();
}

extern "C" const double liblldb_coreVersionNumber;
const char *
lldb_private::GetVersion ()
{
    static char g_version_string[32];
    if (g_version_string[0] == '\0')
        ::snprintf (g_version_string, sizeof(g_version_string), "LLDB-%g", liblldb_coreVersionNumber);

    return g_version_string;
}

const char *
lldb_private::GetVoteAsCString (Vote vote)
{
    switch (vote)
    {
    case eVoteNo:           return "no";
    case eVoteNoOpinion:    return "no opinion";
    case eVoteYes:          return "yes";
    default:
        break;
    }
    return "invalid";
}

const char *
lldb_private::GetSectionTypeAsCString (SectionType sect_type)
{
    switch (sect_type)
    {
    case eSectionTypeInvalid: return "invalid";
    case eSectionTypeCode: return "code";
    case eSectionTypeContainer: return "container";
    case eSectionTypeData: return "data";
    case eSectionTypeDataCString: return "data-cstr";
    case eSectionTypeDataCStringPointers: return "data-cstr-ptr";
    case eSectionTypeDataSymbolAddress: return "data-symbol-addr";
    case eSectionTypeData4: return "data-4-byte";
    case eSectionTypeData8: return "data-8-byte";
    case eSectionTypeData16: return "data-16-byte";
    case eSectionTypeDataPointers: return "data-ptrs";
    case eSectionTypeDebug: return "debug";
    case eSectionTypeZeroFill: return "zero-fill";
    case eSectionTypeDataObjCMessageRefs: return "objc-message-refs";
    case eSectionTypeDataObjCCFStrings: return "objc-cfstrings";
    case eSectionTypeDWARFDebugAbbrev: return "dwarf-abbrev";
    case eSectionTypeDWARFDebugAranges: return "dwarf-aranges";
    case eSectionTypeDWARFDebugFrame: return "dwarf-frame";
    case eSectionTypeDWARFDebugInfo: return "dwarf-info";
    case eSectionTypeDWARFDebugLine: return "dwarf-line";
    case eSectionTypeDWARFDebugLoc: return "dwarf-loc";
    case eSectionTypeDWARFDebugMacInfo: return "dwarf-macinfo";
    case eSectionTypeDWARFDebugPubNames: return "dwarf-pubnames";
    case eSectionTypeDWARFDebugPubTypes: return "dwarf-pubtypes";
    case eSectionTypeDWARFDebugRanges: return "dwarf-ranges";
    case eSectionTypeDWARFDebugStr: return "dwarf-str";
    case eSectionTypeDWARFAppleNames: return "apple-names";
    case eSectionTypeDWARFAppleTypes: return "apple-types";
    case eSectionTypeDWARFAppleNamespaces: return "apple-namespaces";
    case eSectionTypeDWARFAppleObjC: return "apple-objc";
    case eSectionTypeEHFrame: return "eh-frame";
    case eSectionTypeOther: return "regular";
    }
    return "unknown";

}

bool
lldb_private::NameMatches (const char *name,
                           NameMatchType match_type,
                           const char *match)
{
    if (match_type == eNameMatchIgnore)
        return true;

    if (name == match)
        return true;

    if (name && match)
    {
        llvm::StringRef name_sref(name);
        llvm::StringRef match_sref(match);
        switch (match_type)
        {
        case eNameMatchIgnore:
            return true;
        case eNameMatchEquals:      return name_sref == match_sref;
        case eNameMatchContains:    return name_sref.find (match_sref) != llvm::StringRef::npos;
        case eNameMatchStartsWith:  return name_sref.startswith (match_sref);
        case eNameMatchEndsWith:    return name_sref.endswith (match_sref);
        case eNameMatchRegularExpression:
            {
                RegularExpression regex (match);
                return regex.Execute (name);
            }
            break;
        default:
            assert (!"unhandled NameMatchType in lldb_private::NameMatches()");
            break;
        }
    }
    return false;
}
<commit_msg>Register the ProcessGDBRemote plugin ahead of the ProcessKDP plugin so a process connect without any plugin specified picks up the  gdb-remote plugin by default.<commit_after>//===-- lldb.cpp ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-private.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

#include "llvm/ADT/StringRef.h"

#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVM.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h"
#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h"
#include "Plugins/Platform/Linux/PlatformLinux.h"
#if defined (__APPLE__)
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
#include "Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.h"
#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
#include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
#endif

#include "Plugins/Process/mach-core/ProcessMachCore.h"

#if defined (__linux__)
#include "Plugins/Process/Linux/ProcessLinux.h"
#endif

#if defined (__FreeBSD__)
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Process/POSIX/ProcessPOSIX.h"
#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
#endif

#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"

using namespace lldb;
using namespace lldb_private;

void
lldb_private::Initialize ()
{
    // Make sure we inialize only once
    static Mutex g_inited_mutex(Mutex::eMutexTypeRecursive);
    static bool g_inited = false;

    Mutex::Locker locker(g_inited_mutex);
    if (!g_inited)
    {
        g_inited = true;
        Log::Initialize();
        Timer::Initialize ();
        Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

        ABIMacOSX_i386::Initialize();
        ABIMacOSX_arm::Initialize();
        ABISysV_x86_64::Initialize();
        DisassemblerLLVMC::Initialize();
        DisassemblerLLVM::Initialize();
        ObjectContainerBSDArchive::Initialize();
        ObjectFileELF::Initialize();
        SymbolFileDWARF::Initialize();
        SymbolFileSymtab::Initialize();
        UnwindAssemblyInstEmulation::Initialize();
        UnwindAssembly_x86::Initialize();
        EmulateInstructionARM::Initialize ();
        ObjectFilePECOFF::Initialize ();
        DynamicLoaderPOSIXDYLD::Initialize ();
        PlatformFreeBSD::Initialize();
        PlatformLinux::Initialize();
#if defined (__APPLE__)
        //----------------------------------------------------------------------
        // Apple/Darwin hosted plugins
        //----------------------------------------------------------------------
        DynamicLoaderMacOSXDYLD::Initialize();
        DynamicLoaderDarwinKernel::Initialize();
        OperatingSystemDarwinKernel::Initialize();
        SymbolFileDWARFDebugMap::Initialize();
        ItaniumABILanguageRuntime::Initialize();
        AppleObjCRuntimeV2::Initialize();
        AppleObjCRuntimeV1::Initialize();
        ObjectContainerUniversalMachO::Initialize();
        ObjectFileMachO::Initialize();
        ProcessGDBRemote::Initialize();
        ProcessKDP::Initialize();
        ProcessMachCore::Initialize();
        SymbolVendorMacOSX::Initialize();
        PlatformRemoteiOS::Initialize();
        PlatformMacOSX::Initialize();
        PlatformiOSSimulator::Initialize();
#endif
#if defined (__linux__)
        //----------------------------------------------------------------------
        // Linux hosted plugins
        //----------------------------------------------------------------------
        ProcessLinux::Initialize();
#endif
#if defined (__FreeBSD__)
        ProcessFreeBSD::Initialize();
        ProcessGDBRemote::Initialize();
#endif
        //----------------------------------------------------------------------
        // Platform agnostic plugins
        //----------------------------------------------------------------------
        PlatformRemoteGDBServer::Initialize ();
        DynamicLoaderStatic::Initialize();

        // Scan for any system or user LLDB plug-ins
        PluginManager::Initialize();

        // The process settings need to know about installed plug-ins, so the Settings must be initialized
        // AFTER PluginManager::Initialize is called.

        Debugger::SettingsInitialize();
    }
}

void
lldb_private::WillTerminate()
{
    Host::WillTerminate();
}

void
lldb_private::Terminate ()
{
    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

    // Terminate and unload and loaded system or user LLDB plug-ins
    PluginManager::Terminate();

    ABIMacOSX_i386::Terminate();
    ABIMacOSX_arm::Terminate();
    ABISysV_x86_64::Terminate();
    DisassemblerLLVMC::Terminate();
    DisassemblerLLVM::Terminate();
    ObjectContainerBSDArchive::Terminate();
    ObjectFileELF::Terminate();
    SymbolFileDWARF::Terminate();
    SymbolFileSymtab::Terminate();
    UnwindAssembly_x86::Terminate();
    UnwindAssemblyInstEmulation::Terminate();
    EmulateInstructionARM::Terminate ();
    ObjectFilePECOFF::Terminate ();
    DynamicLoaderPOSIXDYLD::Terminate ();
    PlatformFreeBSD::Terminate();
    PlatformLinux::Terminate();
#if defined (__APPLE__)
    DynamicLoaderMacOSXDYLD::Terminate();
    DynamicLoaderDarwinKernel::Terminate();
    OperatingSystemDarwinKernel::Terminate();
    SymbolFileDWARFDebugMap::Terminate();
    ItaniumABILanguageRuntime::Terminate();
    AppleObjCRuntimeV2::Terminate();
    AppleObjCRuntimeV1::Terminate();
    ObjectContainerUniversalMachO::Terminate();
    ObjectFileMachO::Terminate();
    ProcessMachCore::Terminate();
    ProcessGDBRemote::Terminate();
    ProcessKDP::Terminate();
    SymbolVendorMacOSX::Terminate();
    PlatformMacOSX::Terminate();
    PlatformRemoteiOS::Terminate();
    PlatformiOSSimulator::Terminate();
#endif

    Debugger::SettingsTerminate ();

#if defined (__linux__)
    ProcessLinux::Terminate();
#endif

#if defined (__FreeBSD__)
    ProcessFreeBSD::Terminate();
    ProcessGDBRemote::Terminate();
#endif

    DynamicLoaderStatic::Terminate();

    Log::Terminate();
}

extern "C" const double liblldb_coreVersionNumber;
const char *
lldb_private::GetVersion ()
{
    static char g_version_string[32];
    if (g_version_string[0] == '\0')
        ::snprintf (g_version_string, sizeof(g_version_string), "LLDB-%g", liblldb_coreVersionNumber);

    return g_version_string;
}

const char *
lldb_private::GetVoteAsCString (Vote vote)
{
    switch (vote)
    {
    case eVoteNo:           return "no";
    case eVoteNoOpinion:    return "no opinion";
    case eVoteYes:          return "yes";
    default:
        break;
    }
    return "invalid";
}

const char *
lldb_private::GetSectionTypeAsCString (SectionType sect_type)
{
    switch (sect_type)
    {
    case eSectionTypeInvalid: return "invalid";
    case eSectionTypeCode: return "code";
    case eSectionTypeContainer: return "container";
    case eSectionTypeData: return "data";
    case eSectionTypeDataCString: return "data-cstr";
    case eSectionTypeDataCStringPointers: return "data-cstr-ptr";
    case eSectionTypeDataSymbolAddress: return "data-symbol-addr";
    case eSectionTypeData4: return "data-4-byte";
    case eSectionTypeData8: return "data-8-byte";
    case eSectionTypeData16: return "data-16-byte";
    case eSectionTypeDataPointers: return "data-ptrs";
    case eSectionTypeDebug: return "debug";
    case eSectionTypeZeroFill: return "zero-fill";
    case eSectionTypeDataObjCMessageRefs: return "objc-message-refs";
    case eSectionTypeDataObjCCFStrings: return "objc-cfstrings";
    case eSectionTypeDWARFDebugAbbrev: return "dwarf-abbrev";
    case eSectionTypeDWARFDebugAranges: return "dwarf-aranges";
    case eSectionTypeDWARFDebugFrame: return "dwarf-frame";
    case eSectionTypeDWARFDebugInfo: return "dwarf-info";
    case eSectionTypeDWARFDebugLine: return "dwarf-line";
    case eSectionTypeDWARFDebugLoc: return "dwarf-loc";
    case eSectionTypeDWARFDebugMacInfo: return "dwarf-macinfo";
    case eSectionTypeDWARFDebugPubNames: return "dwarf-pubnames";
    case eSectionTypeDWARFDebugPubTypes: return "dwarf-pubtypes";
    case eSectionTypeDWARFDebugRanges: return "dwarf-ranges";
    case eSectionTypeDWARFDebugStr: return "dwarf-str";
    case eSectionTypeDWARFAppleNames: return "apple-names";
    case eSectionTypeDWARFAppleTypes: return "apple-types";
    case eSectionTypeDWARFAppleNamespaces: return "apple-namespaces";
    case eSectionTypeDWARFAppleObjC: return "apple-objc";
    case eSectionTypeEHFrame: return "eh-frame";
    case eSectionTypeOther: return "regular";
    }
    return "unknown";

}

bool
lldb_private::NameMatches (const char *name,
                           NameMatchType match_type,
                           const char *match)
{
    if (match_type == eNameMatchIgnore)
        return true;

    if (name == match)
        return true;

    if (name && match)
    {
        llvm::StringRef name_sref(name);
        llvm::StringRef match_sref(match);
        switch (match_type)
        {
        case eNameMatchIgnore:
            return true;
        case eNameMatchEquals:      return name_sref == match_sref;
        case eNameMatchContains:    return name_sref.find (match_sref) != llvm::StringRef::npos;
        case eNameMatchStartsWith:  return name_sref.startswith (match_sref);
        case eNameMatchEndsWith:    return name_sref.endswith (match_sref);
        case eNameMatchRegularExpression:
            {
                RegularExpression regex (match);
                return regex.Execute (name);
            }
            break;
        default:
            assert (!"unhandled NameMatchType in lldb_private::NameMatches()");
            break;
        }
    }
    return false;
}
<|endoftext|>


<commit_before>/* Lantern - A path tracer
*
* Lantern is the legal property of Adrian Astley
* Copyright Adrian Astley 2015 - 2016
*/

#include "scene/scene.h"
#include "scene/geometry_generator.h"
#include "scene/lambert_material.h"

#include "visualizer/visualizer.h"

#include "renderer/renderer.h"

#include <xmmintrin.h>
#include <pmmintrin.h>

int main(int argc, const char *argv[]) {
	_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
	_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);

	Lantern::Scene scene;
	Lantern::Mesh cube;
	Lantern::CreateBox(4.0f, 4.0f, 4.0f, &cube);
	Lantern::TranslateMesh(float3(0.0f, -2.0f, 0.0f), &cube);

	Lantern::Mesh sphere;
	Lantern::CreateGeosphere(1.0f, 3u, &sphere);
	Lantern::TranslateMesh(float3(0.0f, 1.0f, 0.0f), &sphere);

	Lantern::LambertMaterial *grayMaterial = new Lantern::LambertMaterial(float3(0.5f, 0.5f, 0.5f), float3(0.0f));
	scene.AddMesh(&cube, grayMaterial);
	scene.AddMesh(&sphere, grayMaterial);
	scene.Commit();

	Lantern::Renderer renderer(&scene);

	bool visualizing = true;
	if (visualizing) {
		Lantern::Visualizer visualizer(&renderer, &scene);
		visualizer.Run();
	} else {
		// renderer.Run();
	}

	delete grayMaterial;
}
<commit_msg>Create the 9 balls scene<commit_after>/* Lantern - A path tracer
*
* Lantern is the legal property of Adrian Astley
* Copyright Adrian Astley 2015 - 2016
*/

#include "scene/scene.h"
#include "scene/geometry_generator.h"
#include "scene/lambert_material.h"
#include "scene/mirror.h"

#include "visualizer/visualizer.h"

#include "renderer/renderer.h"

#include <xmmintrin.h>
#include <pmmintrin.h>

int main(int argc, const char *argv[]) {
	_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
	_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);

	Lantern::Scene scene;
	scene.SetCamera(M_PI_2, 0.0f, 20.0f, 1280.0f, 720.0f);

	// Create the materials
	Lantern::LambertMaterial gray(float3(0.9f, 0.9f, 0.9f), float3(0.0f));
	Lantern::LambertMaterial green(float3(0.408f, 0.741f, 0.467f), float3(0.0f));
	Lantern::LambertMaterial blue(float3(0.392f, 0.584f, 0.929f), float3(0.0f));
	Lantern::LambertMaterial orange(float3(1.0f, 0.498f, 0.314f), float3(0.0f));
	Lantern::LambertMaterial whiteEmmisive(float3(1.0f, 1.0f, 1.0f), float3(3.0f));
	Lantern::MirrorMaterial mirror(float3(0.95f, 0.95f, 0.95f));

	// Create the floor
	Lantern::Mesh floorMesh;
	Lantern::CreateGrid(50.0f, 50.0f, 2u, 2u, &floorMesh);
	Lantern::TranslateMesh(float3(0.0f, -6.0f, 0.0f), &floorMesh);
	scene.AddMesh(&floorMesh, &gray);

	// Create the 9 spheres
	Lantern::Mesh sphere;
	Lantern::CreateGeosphere(2.0f, 2u, &sphere);

	scene.AddMesh(&sphere, &whiteEmmisive);

	Lantern::TranslateMesh(float3(-4.0f, -4.0f, -4.0f), &sphere);
	scene.AddMesh(&sphere, &green);

	Lantern::TranslateMesh(float3(0.0f, 0.0f, 8.0f), &sphere);
	scene.AddMesh(&sphere, &blue);

	Lantern::TranslateMesh(float3(0.0f, 8.0f, 0.0f), &sphere);
	scene.AddMesh(&sphere, &mirror);

	Lantern::TranslateMesh(float3(0.0f, 0.0f, -8.0f), &sphere);
	scene.AddMesh(&sphere, &orange);

	Lantern::TranslateMesh(float3(8.0f, 0.0f, 0.0f), &sphere);
	scene.AddMesh(&sphere, &blue);

	Lantern::TranslateMesh(float3(0.0f, 0.0f, 8.0f), &sphere);
	scene.AddMesh(&sphere, &green);

	Lantern::TranslateMesh(float3(0.0f, -8.0f, 0.0f), &sphere);
	scene.AddMesh(&sphere, &orange);

	Lantern::TranslateMesh(float3(0.0f, 0.0f, -8.0f), &sphere);
	scene.AddMesh(&sphere, &mirror);

	scene.Commit();

	Lantern::Renderer renderer(&scene);

	bool visualizing = true;
	if (visualizing) {
		Lantern::Visualizer visualizer(&renderer, &scene);
		visualizer.Run();
	} else {
		// renderer.Run();
	}
}
<|endoftext|>


<commit_before>#include "aquila/global.h"
#include "aquila/ml/Dtw.h"
#include <unittestpp.h>
#include <vector>

SUITE(Dtw)
{
    TEST(DistanceToItself)
    {
        const std::size_t SIZE = 3;
        double arr1[SIZE] = {0, 1, 2}, arr2[SIZE] = {1, 2, 3};
        std::vector<double> v1(arr1, arr1 + SIZE), v2(arr2, arr2 + SIZE);

        Aquila::DtwDataType from, to;
        from.push_back(v1);
        from.push_back(v2);
        to.push_back(v1);
        to.push_back(v2);

        Aquila::Dtw dtw;
        double distance = dtw.getDistance(from, to);

        CHECK_CLOSE(0.0, distance, 0.000001);
    }
}

<commit_msg>Test for DTW zero distance along diagonal<commit_after>#include "aquila/global.h"
#include "aquila/ml/Dtw.h"
#include <unittestpp.h>
#include <vector>

SUITE(Dtw)
{
    TEST(DistanceToItself)
    {
        const std::size_t SIZE = 3;
        double arr1[SIZE] = {0, 1, 2}, arr2[SIZE] = {1, 2, 3};
        std::vector<double> v1(arr1, arr1 + SIZE), v2(arr2, arr2 + SIZE);

        Aquila::DtwDataType from, to;
        from.push_back(v1);
        from.push_back(v2);
        to.push_back(v1);
        to.push_back(v2);

        Aquila::Dtw dtw;
        double distance = dtw.getDistance(from, to);

        CHECK_CLOSE(0.0, distance, 0.000001);
    }

    TEST(ZeroDiagonalDistance)
    {
        const std::size_t SIZE = 3;
        double arr1[SIZE] = {0, 0, 0}, arr2[SIZE] = {1, 1, 1};
        std::vector<double> zeros(arr1, arr1 + SIZE), ones(arr2, arr2 + SIZE);

        Aquila::DtwDataType from, to;
        from.push_back(zeros);
        from.push_back(ones);
        from.push_back(ones);
        to.push_back(zeros);
        to.push_back(ones);
        to.push_back(ones);

        /**
         * this will give the following local Manhattan distances:
         *
         * 3 0 0
         * 3 0 0
         * 0 3 3
         *
         * and the lowest-cost path will be on the diagonal.
         */

        Aquila::Dtw dtw(Aquila::manhattanDistance);
        double distance = dtw.getDistance(from, to);

        CHECK_CLOSE(0.0, distance, 0.000001);
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Nathan Osman
 *
 * 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 <QFile>
#include <QFileInfo>
#include <QFileInfoList>
#include <QUrl>

#include "QHttpEngine/qfilesystemhandler.h"
#include "QHttpEngine/qiodevicecopier.h"
#include "qfilesystemhandler_p.h"

// Template for listing directory contents
const QString ListTemplate =
        "<!DOCTYPE html><meta charset=\"utf-8\"><title>%1</title>"
        "
%1

Directory listing:

%2

"
        "QHttpEngine %3";

QFilesystemHandlerPrivate::QFilesystemHandlerPrivate(QFilesystemHandler *handler)
    : QObject(handler),
      q(handler)
{
}

bool QFilesystemHandlerPrivate::absolutePath(const QString &path, QString &absolutePath)
{
    // Clean the path and make it absolute
    absolutePath = QDir(documentRoot.absoluteFilePath(path)).canonicalPath();

    // Ensure that the absolute path is within the root
    return absolutePath.startsWith(documentRoot.canonicalPath());
}

QByteArray QFilesystemHandlerPrivate::mimeType(const QString &absolutePath)
{
    // Query the MIME database based on the filename and contents
    return database.mimeTypeForFile(absolutePath).name().toUtf8();
}

void QFilesystemHandlerPrivate::processFile(QHttpSocket *socket, const QString &absolutePath)
{
    // Attempt to open the file for reading
    QFile *file = new QFile(absolutePath);
    if(!file->open(QIODevice::ReadOnly)) {
        delete file;

        socket->writeError(QHttpSocket::Forbidden);
        return;
    }

    // Create a QIODeviceCopier to copy the file contents to the socket
    QIODeviceCopier *copier = new QIODeviceCopier(file, socket);
    connect(socket, SIGNAL(destroyed()), copier, SLOT(stop()));
    connect(copier, SIGNAL(finished()), copier, SLOT(deleteLater()));
    connect(copier, SIGNAL(finished()), file, SLOT(deleteLater()));

    // Set the mimetype and content length
    socket->setHeader("Content-Type", mimeType(absolutePath));
    socket->setHeader("Content-Length", QByteArray::number(file->size()));
    socket->writeHeaders();

    // Start the copy
    copier->start();
}

void QFilesystemHandlerPrivate::processDirectory(QHttpSocket *socket, const QString &path, const QString &absolutePath)
{
    // Add entries for each of the files
    QString listing;
    foreach(QFileInfo info, QDir(absolutePath).entryInfoList()) {
        listing.append(QString("
%1%2
")
                .arg(info.fileName().toHtmlEscaped())
                .arg(info.isDir() ? "/" : ""));
    }

    // Build the response and convert the string to UTF-8
    QByteArray data = ListTemplate
            .arg("/" + path.toHtmlEscaped())
            .arg(listing)
            .arg(QHTTPENGINE_VERSION)
            .toUtf8();

    // Set the headers and write the content
    socket->setHeader("Content-Type", "text/html");
    socket->setHeader("Content-Length", QByteArray::number(data.length()));
    socket->write(data);
    socket->close();
}

QFilesystemHandler::QFilesystemHandler(QObject *parent)
    : QHttpHandler(parent),
      d(new QFilesystemHandlerPrivate(this))
{
}

QFilesystemHandler::QFilesystemHandler(const QString &documentRoot, QObject *parent)
    : QHttpHandler(parent),
      d(new QFilesystemHandlerPrivate(this))
{
    setDocumentRoot(documentRoot);
}

void QFilesystemHandler::setDocumentRoot(const QString &documentRoot)
{
    d->documentRoot.setPath(documentRoot);
}

void QFilesystemHandler::process(QHttpSocket *socket, const QString &path)
{
    // If a document root is not set, an error has occurred
    if(d->documentRoot.path().isNull()) {
        socket->writeError(QHttpSocket::InternalServerError);
        return;
    }

    // URL-decode the path
    QString decodedPath = QUrl::fromPercentEncoding(path.toUtf8());

    // Attempt to retrieve the absolute path
    QString absolutePath;
    if(!d->absolutePath(decodedPath, absolutePath)) {
        socket->writeError(QHttpSocket::NotFound);
        return;
    }

    if(QFileInfo(absolutePath).isDir()) {
        d->processDirectory(socket, decodedPath, absolutePath);
    } else {
        d->processFile(socket, absolutePath);
    }
}
<commit_msg>Fixed potential security issue with QFilesystemHandler and added ability to use symbolic links in paths (fixes #5).<commit_after>/*
 * Copyright (c) 2015 Nathan Osman
 *
 * 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 <QFile>
#include <QFileInfo>
#include <QFileInfoList>
#include <QUrl>

#include "QHttpEngine/qfilesystemhandler.h"
#include "QHttpEngine/qiodevicecopier.h"
#include "qfilesystemhandler_p.h"

// Template for listing directory contents
const QString ListTemplate =
        "<!DOCTYPE html><meta charset=\"utf-8\"><title>%1</title>"
        "
%1

Directory listing:

%2

"
        "QHttpEngine %3";

QFilesystemHandlerPrivate::QFilesystemHandlerPrivate(QFilesystemHandler *handler)
    : QObject(handler),
      q(handler)
{
}

bool QFilesystemHandlerPrivate::absolutePath(const QString &path, QString &absolutePath)
{
    // Resolve the path according to the document root
    absolutePath = documentRoot.absoluteFilePath(path);

    // Perhaps not the most efficient way of doing things, but one way to
    // determine if path is within the document root is to convert it to a
    // relative path and check to see if it begins with "../" (it shouldn't)
    return documentRoot.exists(absolutePath) && !documentRoot.relativeFilePath(path).startsWith("../");
}

QByteArray QFilesystemHandlerPrivate::mimeType(const QString &absolutePath)
{
    // Query the MIME database based on the filename and contents
    return database.mimeTypeForFile(absolutePath).name().toUtf8();
}

void QFilesystemHandlerPrivate::processFile(QHttpSocket *socket, const QString &absolutePath)
{
    // Attempt to open the file for reading
    QFile *file = new QFile(absolutePath);
    if(!file->open(QIODevice::ReadOnly)) {
        delete file;

        socket->writeError(QHttpSocket::Forbidden);
        return;
    }

    // Create a QIODeviceCopier to copy the file contents to the socket
    QIODeviceCopier *copier = new QIODeviceCopier(file, socket);
    connect(socket, SIGNAL(destroyed()), copier, SLOT(stop()));
    connect(copier, SIGNAL(finished()), copier, SLOT(deleteLater()));
    connect(copier, SIGNAL(finished()), file, SLOT(deleteLater()));

    // Set the mimetype and content length
    socket->setHeader("Content-Type", mimeType(absolutePath));
    socket->setHeader("Content-Length", QByteArray::number(file->size()));
    socket->writeHeaders();

    // Start the copy
    copier->start();
}

void QFilesystemHandlerPrivate::processDirectory(QHttpSocket *socket, const QString &path, const QString &absolutePath)
{
    // Add entries for each of the files
    QString listing;
    foreach(QFileInfo info, QDir(absolutePath).entryInfoList()) {
        listing.append(QString("
%1%2
")
                .arg(info.fileName().toHtmlEscaped())
                .arg(info.isDir() ? "/" : ""));
    }

    // Build the response and convert the string to UTF-8
    QByteArray data = ListTemplate
            .arg("/" + path.toHtmlEscaped())
            .arg(listing)
            .arg(QHTTPENGINE_VERSION)
            .toUtf8();

    // Set the headers and write the content
    socket->setHeader("Content-Type", "text/html");
    socket->setHeader("Content-Length", QByteArray::number(data.length()));
    socket->write(data);
    socket->close();
}

QFilesystemHandler::QFilesystemHandler(QObject *parent)
    : QHttpHandler(parent),
      d(new QFilesystemHandlerPrivate(this))
{
}

QFilesystemHandler::QFilesystemHandler(const QString &documentRoot, QObject *parent)
    : QHttpHandler(parent),
      d(new QFilesystemHandlerPrivate(this))
{
    setDocumentRoot(documentRoot);
}

void QFilesystemHandler::setDocumentRoot(const QString &documentRoot)
{
    d->documentRoot.setPath(documentRoot);
}

void QFilesystemHandler::process(QHttpSocket *socket, const QString &path)
{
    // If a document root is not set, an error has occurred
    if(d->documentRoot.path().isNull()) {
        socket->writeError(QHttpSocket::InternalServerError);
        return;
    }

    // URL-decode the path
    QString decodedPath = QUrl::fromPercentEncoding(path.toUtf8());

    // Attempt to retrieve the absolute path
    QString absolutePath;
    if(!d->absolutePath(decodedPath, absolutePath)) {
        socket->writeError(QHttpSocket::NotFound);
        return;
    }

    if(QFileInfo(absolutePath).isDir()) {
        d->processDirectory(socket, decodedPath, absolutePath);
    } else {
        d->processFile(socket, absolutePath);
    }
}
<|endoftext|>


<commit_before>/**
 * 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.
 */
#ifndef __STOUT_OS_READ_HPP__
#define __STOUT_OS_READ_HPP__

#include <stdio.h>
#include <unistd.h>

#include <stout/error.hpp>
#include <stout/try.hpp>

namespace os {

// Reads 'size' bytes from a file from its current offset.
// If EOF is encountered before reading 'size' bytes then the result
// will contain the bytes read and a subsequent read will return None.
inline Result<std::string> read(int fd, size_t size)
{
  char* buffer = new char[size];
  size_t offset = 0;

  while (offset < size) {
    ssize_t length = ::read(fd, buffer + offset, size - offset);

    if (length < 0) {
      // TODO(bmahler): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
      if (errno == EINTR) {
        continue;
      }
      ErrnoError error; // Constructed before 'delete' to capture errno.
      delete[] buffer;
      return error;
    } else if (length == 0) {
      // Reached EOF before expected! Only return as much data as
      // available or None if we haven't read anything yet.
      if (offset > 0) {
        std::string result(buffer, offset);
        delete[] buffer;
        return result;
      }
      delete[] buffer;
      return None();
    }

    offset += length;
  }

  std::string result(buffer, size);
  delete[] buffer;
  return result;
}

// Returns the contents of the file.
inline Try<std::string> read(const std::string& path)
{
  FILE* file = fopen(path.c_str(), "r");
  if (file == NULL) {
    return ErrnoError("Failed to open file '" + path + "'");
  }

  // Initially the 'line' is NULL and length 0, getline() allocates
  // ('malloc') a buffer for reading the line.
  // In subsequent iterations, if the buffer is not large enough to
  // hold the line, getline() resizes it with 'realloc' and updates
  // 'line' and 'length' as necessary. See:
  // - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html
  // - http://man7.org/linux/man-pages/man3/getline.3.html
  std::string result;
  char* line = NULL;
  size_t length = 0;
  ssize_t read;

  while ((read = getline(&line, &length, file)) != -1) {
    result.append(line, read);
  }

  // getline() requires the line buffer to be freed by the caller.
  free(line);

  if (ferror(file)) {
    ErrnoError error;
    // NOTE: We ignore the error from fclose(). This is because
    // users calling this function are interested in the return value
    // of read(). Also an unsuccessful fclose() does not affect the
    // read.
    fclose(file);
    return error;
  }

  fclose(file);
  return result;
}

} // namespace os {

#endif // __STOUT_OS_READ_HPP__
<commit_msg>Add missing include to stout/os/read.hpp.<commit_after>/**
 * 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.
 */
#ifndef __STOUT_OS_READ_HPP__
#define __STOUT_OS_READ_HPP__

#include <stdio.h>
#include <unistd.h>

#include <stout/error.hpp>
#include <stout/result.hpp>
#include <stout/try.hpp>

namespace os {

// Reads 'size' bytes from a file from its current offset.
// If EOF is encountered before reading 'size' bytes then the result
// will contain the bytes read and a subsequent read will return None.
inline Result<std::string> read(int fd, size_t size)
{
  char* buffer = new char[size];
  size_t offset = 0;

  while (offset < size) {
    ssize_t length = ::read(fd, buffer + offset, size - offset);

    if (length < 0) {
      // TODO(bmahler): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
      if (errno == EINTR) {
        continue;
      }
      ErrnoError error; // Constructed before 'delete' to capture errno.
      delete[] buffer;
      return error;
    } else if (length == 0) {
      // Reached EOF before expected! Only return as much data as
      // available or None if we haven't read anything yet.
      if (offset > 0) {
        std::string result(buffer, offset);
        delete[] buffer;
        return result;
      }
      delete[] buffer;
      return None();
    }

    offset += length;
  }

  std::string result(buffer, size);
  delete[] buffer;
  return result;
}

// Returns the contents of the file.
inline Try<std::string> read(const std::string& path)
{
  FILE* file = fopen(path.c_str(), "r");
  if (file == NULL) {
    return ErrnoError("Failed to open file '" + path + "'");
  }

  // Initially the 'line' is NULL and length 0, getline() allocates
  // ('malloc') a buffer for reading the line.
  // In subsequent iterations, if the buffer is not large enough to
  // hold the line, getline() resizes it with 'realloc' and updates
  // 'line' and 'length' as necessary. See:
  // - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html
  // - http://man7.org/linux/man-pages/man3/getline.3.html
  std::string result;
  char* line = NULL;
  size_t length = 0;
  ssize_t read;

  while ((read = getline(&line, &length, file)) != -1) {
    result.append(line, read);
  }

  // getline() requires the line buffer to be freed by the caller.
  free(line);

  if (ferror(file)) {
    ErrnoError error;
    // NOTE: We ignore the error from fclose(). This is because
    // users calling this function are interested in the return value
    // of read(). Also an unsuccessful fclose() does not affect the
    // read.
    fclose(file);
    return error;
  }

  fclose(file);
  return result;
}

} // namespace os {

#endif // __STOUT_OS_READ_HPP__
<|endoftext|>


<commit_before>#include "parametric_shapes.hpp"
#include "core/Log.h"

#include <glm/glm.hpp>

#include <array>
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>

bonobo::mesh_data
parametric_shapes::createQuad(unsigned int width, unsigned int height)
{
	//! \todo Fill in the blanks
	auto const vertices = std::array<glm::vec3, 4>{
		glm::vec3(0.0f,                      0.0f,                       0.0f),
		glm::vec3(static_cast<float>(width), 0.0f,                       0.0f),
		glm::vec3(static_cast<float>(width), static_cast<float>(height), 0.0f),
		glm::vec3(0.0f,                      static_cast<float>(height), 0.0f)
	};

	auto const indices = std::array<glm::uvec3, 2>{
		glm::uvec3(0u, 1u, 2u),
		glm::uvec3(0u, 2u, 3u)
	};

	bonobo::mesh_data data;

	//
	// NOTE:
	//
	// Only the values preceeded by a `\todo` tag should be changed, the
	// other ones are correct!
	//

	// Create a Vertex Array Object: it will remember where we stored the
	// data on the GPU, and  which part corresponds to the vertices, which
	// one for the normals, etc.
	//
	// The following function will create new Vertex Arrays, and pass their
	// name in the given array (second argument). Since we only need one,
	// pass a pointer to `data.vao`.
	glGenVertexArrays(1, /*! \todo fill me */nullptr);

	// To be able to store information, the Vertex Array has to be bound
	// first.
	glBindVertexArray(/*! \todo bind the previously generated Vertex Array */0u);

	// To store the data, we need to allocate buffers on the GPU. Let's
	// allocate a first one for the vertices.
	//
	// The following function's syntax is similar to `glGenVertexArray()`:
	// it will create multiple OpenGL objects, in this case buffers, and
	// return their names in an array. Have the buffer's name stored into
	// `data.bo`.
	glGenBuffers(1, /*! \todo fill me */nullptr);

	// Similar to the Vertex Array, we need to bind it first before storing
	// anything in it. The data stored in it can be interpreted in
	// different ways. Here, we will say that it is just a simple 1D-array
	// and therefore bind the buffer to the corresponding target.
	glBindBuffer(GL_ARRAY_BUFFER, /*! \todo bind the previously generated Buffer */0u);

	glBufferData(GL_ARRAY_BUFFER, /*! \todo how many bytes should the buffer contain? */0u,
	             /* where is the data stored on the CPU? */vertices.data(),
	             /* inform OpenGL that the data is modified once, but used often */GL_STATIC_DRAW);

	// Vertices have been just stored into a buffer, but we still need to
	// tell Vertex Array where to find them, and how to interpret the data
	// within that buffer.
	//
	// You will see shaders in more detail in lab 3, but for now they are
	// just pieces of code running on the GPU and responsible for moving
	// all the vertices to clip space, and assigning a colour to each pixel
	// covered by geometry.
	// Those shaders have inputs, some of them are the data we just stored
	// in a buffer object. We need to tell the Vertex Array which inputs
	// are enabled, and this is done by the following line of code, which
	// enables the input for vertices:
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::vertices));

	// Once an input is enabled, we need to explain where the data comes
	// from, and how it interpret it. When calling the following function,
	// the Vertex Array will automatically use the current buffer bound to
	// GL_ARRAY_BUFFER as its source for the data. How to interpret it is
	// specified below:
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::vertices),
	                      /*! \todo how many components do our vertices have? */0,
	                      /* what is the type of each component? */GL_FLOAT,
	                      /* should it automatically normalise the values stored */GL_FALSE,
	                      /* once all components of a vertex have been read, how far away (in bytes) is the next vertex? */0,
	                      /* how far away (in bytes) from the start of the buffer is the first vertex? */reinterpret_cast<GLvoid const*>(0x0));

	// Now, let's allocate a second one for the indices.
	//
	// Have the buffer's name stored into `data.ibo`.
	glGenBuffers(1, /*! \todo fill me */nullptr);

	// We still want a 1D-array, but this time it should be a 1D-array of
	// elements, aka. indices!
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, /*! \todo bind the previously generated Buffer */0u);

	glBufferData(GL_ELEMENT_ARRAY_BUFFER, /*! \todo how many bytes should the buffer contain? */0u,
	             /* where is the data stored on the CPU? */indices.data(),
	             /* inform OpenGL that the data is modified once, but used often */GL_STATIC_DRAW);

	data.indices_nb = /*! \todo how many indices do we have? */0u;

	// All the data has been recorded, we can unbind them.
	glBindVertexArray(0u);
	glBindBuffer(GL_ARRAY_BUFFER, 0u);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0u);

	return data;
}

bonobo::mesh_data
parametric_shapes::createSphere(unsigned int const res_theta,
                                unsigned int const res_phi, float const radius)
{

	//! \todo (Optional) Implement this function
	return bonobo::mesh_data();
}

bonobo::mesh_data
parametric_shapes::createTorus(unsigned int const res_theta,
                               unsigned int const res_phi, float const rA,
                               float const rB)
{
	//! \todo (Optional) Implement this function
	return bonobo::mesh_data();
}

bonobo::mesh_data
parametric_shapes::createCircleRing(unsigned int const res_radius,
                                    unsigned int const res_theta,
                                    float const inner_radius,
                                    float const outer_radius)
{
	auto const vertices_nb = res_radius * res_theta;

	auto vertices  = std::vector<glm::vec3>(vertices_nb);
	auto normals   = std::vector<glm::vec3>(vertices_nb);
	auto texcoords = std::vector<glm::vec3>(vertices_nb);
	auto tangents  = std::vector<glm::vec3>(vertices_nb);
	auto binormals = std::vector<glm::vec3>(vertices_nb);

	float theta = 0.0f,                                                           // 'stepping'-variable for theta: will go 0 - 2PI
	      dtheta = glm::two_pi<float>() / (static_cast<float>(res_theta) - 1.0f); // step size, depending on the resolution

	float radius = 0.0f,                                                                     // 'stepping'-variable for radius: will go inner_radius - outer_radius
	      dradius = (outer_radius - inner_radius) / (static_cast<float>(res_radius) - 1.0f); // step size, depending on the resolution

	// generate vertices iteratively
	size_t index = 0u;
	for (unsigned int i = 0u; i < res_theta; ++i) {
		float cos_theta = std::cos(theta),
		      sin_theta = std::sin(theta);

		radius = inner_radius;

		for (unsigned int j = 0u; j < res_radius; ++j) {
			// vertex
			vertices[index] = glm::vec3(radius * cos_theta,
			                            radius * sin_theta,
			                            0.0f);

			// texture coordinates
			texcoords[index] = glm::vec3(static_cast<float>(j) / (static_cast<float>(res_radius) - 1.0f),
			                             static_cast<float>(i) / (static_cast<float>(res_theta)  - 1.0f),
			                             0.0f);

			// tangent
			auto t = glm::vec3(cos_theta, sin_theta, 0.0f);
			t = glm::normalize(t);
			tangents[index] = t;

			// binormal
			auto b = glm::vec3(-sin_theta, cos_theta, 0.0f);
			b = glm::normalize(b);
			binormals[index] = b;

			// normal
			auto const n = glm::cross(t, b);
			normals[index] = n;

			radius += dradius;
			++index;
		}

		theta += dtheta;
	}

	// create index array
	auto indices = std::vector<glm::uvec3>(2u * (res_theta - 1u) * (res_radius - 1u));

	// generate indices iteratively
	index = 0u;
	for (unsigned int i = 0u; i < res_theta - 1u; ++i)
	{
		for (unsigned int j = 0u; j < res_radius - 1u; ++j)
		{
			indices[index] = glm::uvec3(res_radius * i + j,
			                            res_radius * i + j + 1u,
			                            res_radius * i + j + 1u + res_radius);
			++index;

			indices[index] = glm::uvec3(res_radius * i + j,
			                            res_radius * i + j + res_radius + 1u,
			                            res_radius * i + j + res_radius);
			++index;
		}
	}

	bonobo::mesh_data data;
	glGenVertexArrays(1, &data.vao);
	assert(data.vao != 0u);
	glBindVertexArray(data.vao);

	auto const vertices_offset = 0u;
	auto const vertices_size = static_cast<GLsizeiptr>(vertices.size() * sizeof(glm::vec3));
	auto const normals_offset = vertices_size;
	auto const normals_size = static_cast<GLsizeiptr>(normals.size() * sizeof(glm::vec3));
	auto const texcoords_offset = normals_offset + normals_size;
	auto const texcoords_size = static_cast<GLsizeiptr>(texcoords.size() * sizeof(glm::vec3));
	auto const tangents_offset = texcoords_offset + texcoords_size;
	auto const tangents_size = static_cast<GLsizeiptr>(tangents.size() * sizeof(glm::vec3));
	auto const binormals_offset = tangents_offset + tangents_size;
	auto const binormals_size = static_cast<GLsizeiptr>(binormals.size() * sizeof(glm::vec3));
	auto const bo_size = static_cast<GLsizeiptr>(vertices_size
	                                            +normals_size
	                                            +texcoords_size
	                                            +tangents_size
	                                            +binormals_size
	                                            );
	glGenBuffers(1, &data.bo);
	assert(data.bo != 0u);
	glBindBuffer(GL_ARRAY_BUFFER, data.bo);
	glBufferData(GL_ARRAY_BUFFER, bo_size, nullptr, GL_STATIC_DRAW);

	glBufferSubData(GL_ARRAY_BUFFER, vertices_offset, vertices_size, static_cast<GLvoid const*>(vertices.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::vertices));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::vertices), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(0x0));

	glBufferSubData(GL_ARRAY_BUFFER, normals_offset, normals_size, static_cast<GLvoid const*>(normals.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::normals));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::normals), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(normals_offset));

	glBufferSubData(GL_ARRAY_BUFFER, texcoords_offset, texcoords_size, static_cast<GLvoid const*>(texcoords.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::texcoords));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::texcoords), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(texcoords_offset));

	glBufferSubData(GL_ARRAY_BUFFER, tangents_offset, tangents_size, static_cast<GLvoid const*>(tangents.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::tangents));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::tangents), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(tangents_offset));

	glBufferSubData(GL_ARRAY_BUFFER, binormals_offset, binormals_size, static_cast<GLvoid const*>(binormals.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::binormals));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::binormals), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(binormals_offset));

	glBindBuffer(GL_ARRAY_BUFFER, 0u);

	data.indices_nb = indices.size() * 3u;
	glGenBuffers(1, &data.ibo);
	assert(data.ibo != 0u);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLsizeiptr>(indices.size() * sizeof(glm::uvec3)), reinterpret_cast<GLvoid const*>(indices.data()), GL_STATIC_DRAW);

	glBindVertexArray(0u);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0u);

	return data;
}
<commit_msg>EDAF80: createSphere should not have been marked as optional<commit_after>#include "parametric_shapes.hpp"
#include "core/Log.h"

#include <glm/glm.hpp>

#include <array>
#include <cassert>
#include <cmath>
#include <iostream>
#include <vector>

bonobo::mesh_data
parametric_shapes::createQuad(unsigned int width, unsigned int height)
{
	//! \todo Fill in the blanks
	auto const vertices = std::array<glm::vec3, 4>{
		glm::vec3(0.0f,                      0.0f,                       0.0f),
		glm::vec3(static_cast<float>(width), 0.0f,                       0.0f),
		glm::vec3(static_cast<float>(width), static_cast<float>(height), 0.0f),
		glm::vec3(0.0f,                      static_cast<float>(height), 0.0f)
	};

	auto const indices = std::array<glm::uvec3, 2>{
		glm::uvec3(0u, 1u, 2u),
		glm::uvec3(0u, 2u, 3u)
	};

	bonobo::mesh_data data;

	//
	// NOTE:
	//
	// Only the values preceeded by a `\todo` tag should be changed, the
	// other ones are correct!
	//

	// Create a Vertex Array Object: it will remember where we stored the
	// data on the GPU, and  which part corresponds to the vertices, which
	// one for the normals, etc.
	//
	// The following function will create new Vertex Arrays, and pass their
	// name in the given array (second argument). Since we only need one,
	// pass a pointer to `data.vao`.
	glGenVertexArrays(1, /*! \todo fill me */nullptr);

	// To be able to store information, the Vertex Array has to be bound
	// first.
	glBindVertexArray(/*! \todo bind the previously generated Vertex Array */0u);

	// To store the data, we need to allocate buffers on the GPU. Let's
	// allocate a first one for the vertices.
	//
	// The following function's syntax is similar to `glGenVertexArray()`:
	// it will create multiple OpenGL objects, in this case buffers, and
	// return their names in an array. Have the buffer's name stored into
	// `data.bo`.
	glGenBuffers(1, /*! \todo fill me */nullptr);

	// Similar to the Vertex Array, we need to bind it first before storing
	// anything in it. The data stored in it can be interpreted in
	// different ways. Here, we will say that it is just a simple 1D-array
	// and therefore bind the buffer to the corresponding target.
	glBindBuffer(GL_ARRAY_BUFFER, /*! \todo bind the previously generated Buffer */0u);

	glBufferData(GL_ARRAY_BUFFER, /*! \todo how many bytes should the buffer contain? */0u,
	             /* where is the data stored on the CPU? */vertices.data(),
	             /* inform OpenGL that the data is modified once, but used often */GL_STATIC_DRAW);

	// Vertices have been just stored into a buffer, but we still need to
	// tell Vertex Array where to find them, and how to interpret the data
	// within that buffer.
	//
	// You will see shaders in more detail in lab 3, but for now they are
	// just pieces of code running on the GPU and responsible for moving
	// all the vertices to clip space, and assigning a colour to each pixel
	// covered by geometry.
	// Those shaders have inputs, some of them are the data we just stored
	// in a buffer object. We need to tell the Vertex Array which inputs
	// are enabled, and this is done by the following line of code, which
	// enables the input for vertices:
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::vertices));

	// Once an input is enabled, we need to explain where the data comes
	// from, and how it interpret it. When calling the following function,
	// the Vertex Array will automatically use the current buffer bound to
	// GL_ARRAY_BUFFER as its source for the data. How to interpret it is
	// specified below:
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::vertices),
	                      /*! \todo how many components do our vertices have? */0,
	                      /* what is the type of each component? */GL_FLOAT,
	                      /* should it automatically normalise the values stored */GL_FALSE,
	                      /* once all components of a vertex have been read, how far away (in bytes) is the next vertex? */0,
	                      /* how far away (in bytes) from the start of the buffer is the first vertex? */reinterpret_cast<GLvoid const*>(0x0));

	// Now, let's allocate a second one for the indices.
	//
	// Have the buffer's name stored into `data.ibo`.
	glGenBuffers(1, /*! \todo fill me */nullptr);

	// We still want a 1D-array, but this time it should be a 1D-array of
	// elements, aka. indices!
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, /*! \todo bind the previously generated Buffer */0u);

	glBufferData(GL_ELEMENT_ARRAY_BUFFER, /*! \todo how many bytes should the buffer contain? */0u,
	             /* where is the data stored on the CPU? */indices.data(),
	             /* inform OpenGL that the data is modified once, but used often */GL_STATIC_DRAW);

	data.indices_nb = /*! \todo how many indices do we have? */0u;

	// All the data has been recorded, we can unbind them.
	glBindVertexArray(0u);
	glBindBuffer(GL_ARRAY_BUFFER, 0u);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0u);

	return data;
}

bonobo::mesh_data
parametric_shapes::createSphere(unsigned int const res_theta,
                                unsigned int const res_phi, float const radius)
{

	//! \todo Implement this function
	return bonobo::mesh_data();
}

bonobo::mesh_data
parametric_shapes::createTorus(unsigned int const res_theta,
                               unsigned int const res_phi, float const rA,
                               float const rB)
{
	//! \todo (Optional) Implement this function
	return bonobo::mesh_data();
}

bonobo::mesh_data
parametric_shapes::createCircleRing(unsigned int const res_radius,
                                    unsigned int const res_theta,
                                    float const inner_radius,
                                    float const outer_radius)
{
	auto const vertices_nb = res_radius * res_theta;

	auto vertices  = std::vector<glm::vec3>(vertices_nb);
	auto normals   = std::vector<glm::vec3>(vertices_nb);
	auto texcoords = std::vector<glm::vec3>(vertices_nb);
	auto tangents  = std::vector<glm::vec3>(vertices_nb);
	auto binormals = std::vector<glm::vec3>(vertices_nb);

	float theta = 0.0f,                                                           // 'stepping'-variable for theta: will go 0 - 2PI
	      dtheta = glm::two_pi<float>() / (static_cast<float>(res_theta) - 1.0f); // step size, depending on the resolution

	float radius = 0.0f,                                                                     // 'stepping'-variable for radius: will go inner_radius - outer_radius
	      dradius = (outer_radius - inner_radius) / (static_cast<float>(res_radius) - 1.0f); // step size, depending on the resolution

	// generate vertices iteratively
	size_t index = 0u;
	for (unsigned int i = 0u; i < res_theta; ++i) {
		float cos_theta = std::cos(theta),
		      sin_theta = std::sin(theta);

		radius = inner_radius;

		for (unsigned int j = 0u; j < res_radius; ++j) {
			// vertex
			vertices[index] = glm::vec3(radius * cos_theta,
			                            radius * sin_theta,
			                            0.0f);

			// texture coordinates
			texcoords[index] = glm::vec3(static_cast<float>(j) / (static_cast<float>(res_radius) - 1.0f),
			                             static_cast<float>(i) / (static_cast<float>(res_theta)  - 1.0f),
			                             0.0f);

			// tangent
			auto t = glm::vec3(cos_theta, sin_theta, 0.0f);
			t = glm::normalize(t);
			tangents[index] = t;

			// binormal
			auto b = glm::vec3(-sin_theta, cos_theta, 0.0f);
			b = glm::normalize(b);
			binormals[index] = b;

			// normal
			auto const n = glm::cross(t, b);
			normals[index] = n;

			radius += dradius;
			++index;
		}

		theta += dtheta;
	}

	// create index array
	auto indices = std::vector<glm::uvec3>(2u * (res_theta - 1u) * (res_radius - 1u));

	// generate indices iteratively
	index = 0u;
	for (unsigned int i = 0u; i < res_theta - 1u; ++i)
	{
		for (unsigned int j = 0u; j < res_radius - 1u; ++j)
		{
			indices[index] = glm::uvec3(res_radius * i + j,
			                            res_radius * i + j + 1u,
			                            res_radius * i + j + 1u + res_radius);
			++index;

			indices[index] = glm::uvec3(res_radius * i + j,
			                            res_radius * i + j + res_radius + 1u,
			                            res_radius * i + j + res_radius);
			++index;
		}
	}

	bonobo::mesh_data data;
	glGenVertexArrays(1, &data.vao);
	assert(data.vao != 0u);
	glBindVertexArray(data.vao);

	auto const vertices_offset = 0u;
	auto const vertices_size = static_cast<GLsizeiptr>(vertices.size() * sizeof(glm::vec3));
	auto const normals_offset = vertices_size;
	auto const normals_size = static_cast<GLsizeiptr>(normals.size() * sizeof(glm::vec3));
	auto const texcoords_offset = normals_offset + normals_size;
	auto const texcoords_size = static_cast<GLsizeiptr>(texcoords.size() * sizeof(glm::vec3));
	auto const tangents_offset = texcoords_offset + texcoords_size;
	auto const tangents_size = static_cast<GLsizeiptr>(tangents.size() * sizeof(glm::vec3));
	auto const binormals_offset = tangents_offset + tangents_size;
	auto const binormals_size = static_cast<GLsizeiptr>(binormals.size() * sizeof(glm::vec3));
	auto const bo_size = static_cast<GLsizeiptr>(vertices_size
	                                            +normals_size
	                                            +texcoords_size
	                                            +tangents_size
	                                            +binormals_size
	                                            );
	glGenBuffers(1, &data.bo);
	assert(data.bo != 0u);
	glBindBuffer(GL_ARRAY_BUFFER, data.bo);
	glBufferData(GL_ARRAY_BUFFER, bo_size, nullptr, GL_STATIC_DRAW);

	glBufferSubData(GL_ARRAY_BUFFER, vertices_offset, vertices_size, static_cast<GLvoid const*>(vertices.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::vertices));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::vertices), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(0x0));

	glBufferSubData(GL_ARRAY_BUFFER, normals_offset, normals_size, static_cast<GLvoid const*>(normals.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::normals));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::normals), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(normals_offset));

	glBufferSubData(GL_ARRAY_BUFFER, texcoords_offset, texcoords_size, static_cast<GLvoid const*>(texcoords.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::texcoords));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::texcoords), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(texcoords_offset));

	glBufferSubData(GL_ARRAY_BUFFER, tangents_offset, tangents_size, static_cast<GLvoid const*>(tangents.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::tangents));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::tangents), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(tangents_offset));

	glBufferSubData(GL_ARRAY_BUFFER, binormals_offset, binormals_size, static_cast<GLvoid const*>(binormals.data()));
	glEnableVertexAttribArray(static_cast<unsigned int>(bonobo::shader_bindings::binormals));
	glVertexAttribPointer(static_cast<unsigned int>(bonobo::shader_bindings::binormals), 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid const*>(binormals_offset));

	glBindBuffer(GL_ARRAY_BUFFER, 0u);

	data.indices_nb = indices.size() * 3u;
	glGenBuffers(1, &data.ibo);
	assert(data.ibo != 0u);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLsizeiptr>(indices.size() * sizeof(glm::uvec3)), reinterpret_cast<GLvoid const*>(indices.data()), GL_STATIC_DRAW);

	glBindVertexArray(0u);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0u);

	return data;
}
<|endoftext|>