<commit_before>/**************************************************************************
 *
 * Copyright 2013 VMware, Inc.
 * 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 <assert.h>

#include "image.hpp"

#include "dxgistate.hpp"

#ifdef __MINGW32__
#define nullptr NULL
#endif
#include "DirectXTex.h"

namespace d3dstate {

static DXGI_FORMAT
ChooseConversionFormat(DXGI_FORMAT Format)
{
    switch (Format) {

    // Float
    case DXGI_FORMAT_R32G32B32A32_FLOAT:
    case DXGI_FORMAT_R32G32B32_FLOAT:
    case DXGI_FORMAT_R16G16B16A16_FLOAT:
    case DXGI_FORMAT_R32G32_FLOAT:
    case DXGI_FORMAT_R11G11B10_FLOAT:
    case DXGI_FORMAT_R16G16_FLOAT:
    case DXGI_FORMAT_R32_FLOAT:
    case DXGI_FORMAT_R16_FLOAT:
    case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
    case DXGI_FORMAT_BC6H_UF16:
    case DXGI_FORMAT_BC6H_SF16:
        return DXGI_FORMAT_R8G8B8A8_UNORM;

    // Unsigned normalized
    case DXGI_FORMAT_R16G16B16A16_UNORM:
    case DXGI_FORMAT_R10G10B10A2_UNORM:
    case DXGI_FORMAT_R8G8B8A8_UNORM:
    case DXGI_FORMAT_R16G16_UNORM:
    case DXGI_FORMAT_R8G8_UNORM:
    case DXGI_FORMAT_R16_UNORM:
    case DXGI_FORMAT_R8_UNORM:
    case DXGI_FORMAT_A8_UNORM:
    case DXGI_FORMAT_R1_UNORM:
    case DXGI_FORMAT_R8G8_B8G8_UNORM:
    case DXGI_FORMAT_G8R8_G8B8_UNORM:
    case DXGI_FORMAT_BC1_UNORM:
    case DXGI_FORMAT_BC2_UNORM:
    case DXGI_FORMAT_BC3_UNORM:
    case DXGI_FORMAT_BC4_UNORM:
    case DXGI_FORMAT_BC5_UNORM:
    case DXGI_FORMAT_B5G6R5_UNORM:
    case DXGI_FORMAT_B5G5R5A1_UNORM:
    case DXGI_FORMAT_B8G8R8A8_UNORM:
    case DXGI_FORMAT_B8G8R8X8_UNORM:
    case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
    case DXGI_FORMAT_BC7_UNORM:
        return DXGI_FORMAT_R8G8B8A8_UNORM;

    // SRGB
    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
    case DXGI_FORMAT_BC1_UNORM_SRGB:
    case DXGI_FORMAT_BC2_UNORM_SRGB:
    case DXGI_FORMAT_BC3_UNORM_SRGB:
    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
    case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
    case DXGI_FORMAT_BC7_UNORM_SRGB:
        return DXGI_FORMAT_R8G8B8A8_UNORM;

    // Signed normalized
    case DXGI_FORMAT_R16G16B16A16_SNORM:
    case DXGI_FORMAT_R8G8B8A8_SNORM:
    case DXGI_FORMAT_R16G16_SNORM:
    case DXGI_FORMAT_R8G8_SNORM:
    case DXGI_FORMAT_R16_SNORM:
    case DXGI_FORMAT_R8_SNORM:
    case DXGI_FORMAT_BC4_SNORM:
    case DXGI_FORMAT_BC5_SNORM:
        return DXGI_FORMAT_R8G8B8A8_SNORM;

    // Unsigned
    case DXGI_FORMAT_R32G32B32A32_UINT:
    case DXGI_FORMAT_R32G32B32_UINT:
    case DXGI_FORMAT_R16G16B16A16_UINT:
    case DXGI_FORMAT_R32G32_UINT:
    case DXGI_FORMAT_R10G10B10A2_UINT:
    case DXGI_FORMAT_R8G8B8A8_UINT:
    case DXGI_FORMAT_R16G16_UINT:
    case DXGI_FORMAT_R32_UINT:
    case DXGI_FORMAT_R8G8_UINT:
    case DXGI_FORMAT_R16_UINT:
    case DXGI_FORMAT_R8_UINT:
        return DXGI_FORMAT_R8G8B8A8_UINT;

    // Signed
    case DXGI_FORMAT_R32G32B32A32_SINT:
    case DXGI_FORMAT_R32G32B32_SINT:
    case DXGI_FORMAT_R16G16B16A16_SINT:
    case DXGI_FORMAT_R32G32_SINT:
    case DXGI_FORMAT_R8G8B8A8_SINT:
    case DXGI_FORMAT_R16G16_SINT:
    case DXGI_FORMAT_R32_SINT:
    case DXGI_FORMAT_R8G8_SINT:
    case DXGI_FORMAT_R16_SINT:
    case DXGI_FORMAT_R8_SINT:
        return DXGI_FORMAT_R8G8B8A8_SINT;

    // Depth
    case DXGI_FORMAT_D32_FLOAT:
    case DXGI_FORMAT_D24_UNORM_S8_UINT:
    case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
    case DXGI_FORMAT_D16_UNORM:
        return DXGI_FORMAT_R8G8B8A8_UNORM;

    // Typeless
    case DXGI_FORMAT_UNKNOWN:
    case DXGI_FORMAT_R32G32B32A32_TYPELESS:
    case DXGI_FORMAT_R32G32B32_TYPELESS:
    case DXGI_FORMAT_R16G16B16A16_TYPELESS:
    case DXGI_FORMAT_R32G32_TYPELESS:
    case DXGI_FORMAT_R32G8X24_TYPELESS:
    case DXGI_FORMAT_R10G10B10A2_TYPELESS:
    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
    case DXGI_FORMAT_R16G16_TYPELESS:
    case DXGI_FORMAT_R32_TYPELESS:
    case DXGI_FORMAT_R8G8_TYPELESS:
    case DXGI_FORMAT_R16_TYPELESS:
    case DXGI_FORMAT_R8_TYPELESS:
    case DXGI_FORMAT_BC1_TYPELESS:
    case DXGI_FORMAT_BC2_TYPELESS:
    case DXGI_FORMAT_BC3_TYPELESS:
    case DXGI_FORMAT_BC4_TYPELESS:
    case DXGI_FORMAT_BC5_TYPELESS:
    case DXGI_FORMAT_B8G8R8A8_TYPELESS:
    case DXGI_FORMAT_B8G8R8X8_TYPELESS:
    case DXGI_FORMAT_BC6H_TYPELESS:
    case DXGI_FORMAT_BC7_TYPELESS:
    case DXGI_FORMAT_R24G8_TYPELESS:
    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
    case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
    case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
        return DXGI_FORMAT_UNKNOWN;

    default:
        return DXGI_FORMAT_R8G8B8A8_UNORM;
    }
}

/**
 * Convert between DXGI formats.
 *
 */
HRESULT
ConvertFormat(DXGI_FORMAT SrcFormat,
              void *SrcData,
              UINT SrcPitch,
              DXGI_FORMAT DstFormat,
              void *DstData,
              UINT DstPitch,
              UINT Width, UINT Height)
{
    HRESULT hr;

    DirectX::Image SrcImage;
    DirectX::Image DstImage;

    SrcImage.width = Width;
    SrcImage.height = Height;
    SrcImage.format = SrcFormat;
    SrcImage.rowPitch = SrcPitch;
    SrcImage.slicePitch = Height * SrcPitch;
    SrcImage.pixels = (uint8_t*)SrcData;

    DstImage.width = Width;
    DstImage.height = Height;
    DstImage.format = DstFormat;
    DstImage.rowPitch = DstPitch;
    DstImage.slicePitch = Height * DstPitch;
    DstImage.pixels = (uint8_t*)DstData;

    DirectX::Rect rect(0, 0, Width, Height);

    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    assert(SUCCEEDED(hr));
    if (FAILED(hr)) {
        return hr;
    }

    if (SrcFormat != DstFormat) {
        DirectX::ScratchImage ScratchImage;
        ScratchImage.Initialize2D(DstFormat, Width, Height, 1, 1);

        hr = DirectX::Convert(SrcImage, DstFormat, DirectX::TEX_FILTER_DEFAULT, 0.0f, ScratchImage);
        if (SUCCEEDED(hr)) {
            hr = CopyRectangle(*ScratchImage.GetImage(0, 0, 0), rect, DstImage, DirectX::TEX_FILTER_DEFAULT, 0, 0);
        }
    } else {
        hr = CopyRectangle(SrcImage, rect, DstImage, DirectX::TEX_FILTER_DEFAULT, 0, 0);
    }

    return hr;
}

image::Image *
ConvertImage(DXGI_FORMAT SrcFormat,
             void *SrcData,
             UINT SrcPitch,
             UINT Width, UINT Height)
{

    DXGI_FORMAT DstFormat = ChooseConversionFormat(SrcFormat);
    if (DstFormat == DXGI_FORMAT_UNKNOWN) {
        return NULL;
    }

    image::Image *image = new image::Image(Width, Height, 4);
    if (!image) {
        return NULL;
    }
    assert(image->stride() > 0);

    HRESULT hr;
    hr = ConvertFormat(SrcFormat,
                       SrcData, SrcPitch,
                       DstFormat,
                       image->start(), image->stride(),
                       Width, Height);
    if (FAILED(hr)) {
        delete image;
        image = NULL;
    }

    return image;
}

} /* namespace d3dstate */
<commit_msg>d3dstate: Dump compressed D3D10/11 textures.<commit_after>/**************************************************************************
 *
 * Copyright 2013 VMware, Inc.
 * 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 <assert.h>

#include <iostream>

#include "image.hpp"

#include "dxgistate.hpp"

#ifdef __MINGW32__
#define nullptr NULL
#endif
#include "DirectXTex.h"

namespace d3dstate {

static DXGI_FORMAT
ChooseConversionFormat(DXGI_FORMAT Format)
{
    switch (Format) {

    // Float
    case DXGI_FORMAT_R32G32B32A32_FLOAT:
    case DXGI_FORMAT_R32G32B32_FLOAT:
    case DXGI_FORMAT_R16G16B16A16_FLOAT:
    case DXGI_FORMAT_R32G32_FLOAT:
    case DXGI_FORMAT_R11G11B10_FLOAT:
    case DXGI_FORMAT_R16G16_FLOAT:
    case DXGI_FORMAT_R32_FLOAT:
    case DXGI_FORMAT_R16_FLOAT:
    case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
    case DXGI_FORMAT_BC6H_UF16:
    case DXGI_FORMAT_BC6H_SF16:
        return DXGI_FORMAT_R8G8B8A8_UNORM;

    // Unsigned normalized
    case DXGI_FORMAT_R16G16B16A16_UNORM:
    case DXGI_FORMAT_R10G10B10A2_UNORM:
    case DXGI_FORMAT_R8G8B8A8_UNORM:
    case DXGI_FORMAT_R16G16_UNORM:
    case DXGI_FORMAT_R8G8_UNORM:
    case DXGI_FORMAT_R16_UNORM:
    case DXGI_FORMAT_R8_UNORM:
    case DXGI_FORMAT_A8_UNORM:
    case DXGI_FORMAT_R1_UNORM:
    case DXGI_FORMAT_R8G8_B8G8_UNORM:
    case DXGI_FORMAT_G8R8_G8B8_UNORM:
    case DXGI_FORMAT_BC1_UNORM:
    case DXGI_FORMAT_BC2_UNORM:
    case DXGI_FORMAT_BC3_UNORM:
    case DXGI_FORMAT_BC4_UNORM:
    case DXGI_FORMAT_BC5_UNORM:
    case DXGI_FORMAT_B5G6R5_UNORM:
    case DXGI_FORMAT_B5G5R5A1_UNORM:
    case DXGI_FORMAT_B8G8R8A8_UNORM:
    case DXGI_FORMAT_B8G8R8X8_UNORM:
    case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
    case DXGI_FORMAT_BC7_UNORM:
        return DXGI_FORMAT_R8G8B8A8_UNORM;

    // SRGB
    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
    case DXGI_FORMAT_BC1_UNORM_SRGB:
    case DXGI_FORMAT_BC2_UNORM_SRGB:
    case DXGI_FORMAT_BC3_UNORM_SRGB:
    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
    case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
    case DXGI_FORMAT_BC7_UNORM_SRGB:
        return DXGI_FORMAT_R8G8B8A8_UNORM;

    // Signed normalized
    case DXGI_FORMAT_R16G16B16A16_SNORM:
    case DXGI_FORMAT_R8G8B8A8_SNORM:
    case DXGI_FORMAT_R16G16_SNORM:
    case DXGI_FORMAT_R8G8_SNORM:
    case DXGI_FORMAT_R16_SNORM:
    case DXGI_FORMAT_R8_SNORM:
    case DXGI_FORMAT_BC4_SNORM:
    case DXGI_FORMAT_BC5_SNORM:
        return DXGI_FORMAT_R8G8B8A8_SNORM;

    // Unsigned
    case DXGI_FORMAT_R32G32B32A32_UINT:
    case DXGI_FORMAT_R32G32B32_UINT:
    case DXGI_FORMAT_R16G16B16A16_UINT:
    case DXGI_FORMAT_R32G32_UINT:
    case DXGI_FORMAT_R10G10B10A2_UINT:
    case DXGI_FORMAT_R8G8B8A8_UINT:
    case DXGI_FORMAT_R16G16_UINT:
    case DXGI_FORMAT_R32_UINT:
    case DXGI_FORMAT_R8G8_UINT:
    case DXGI_FORMAT_R16_UINT:
    case DXGI_FORMAT_R8_UINT:
        return DXGI_FORMAT_R8G8B8A8_UINT;

    // Signed
    case DXGI_FORMAT_R32G32B32A32_SINT:
    case DXGI_FORMAT_R32G32B32_SINT:
    case DXGI_FORMAT_R16G16B16A16_SINT:
    case DXGI_FORMAT_R32G32_SINT:
    case DXGI_FORMAT_R8G8B8A8_SINT:
    case DXGI_FORMAT_R16G16_SINT:
    case DXGI_FORMAT_R32_SINT:
    case DXGI_FORMAT_R8G8_SINT:
    case DXGI_FORMAT_R16_SINT:
    case DXGI_FORMAT_R8_SINT:
        return DXGI_FORMAT_R8G8B8A8_SINT;

    // Depth
    case DXGI_FORMAT_D32_FLOAT:
    case DXGI_FORMAT_D24_UNORM_S8_UINT:
    case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
    case DXGI_FORMAT_D16_UNORM:
        return DXGI_FORMAT_R8G8B8A8_UNORM;

    // Typeless
    case DXGI_FORMAT_UNKNOWN:
    case DXGI_FORMAT_R32G32B32A32_TYPELESS:
    case DXGI_FORMAT_R32G32B32_TYPELESS:
    case DXGI_FORMAT_R16G16B16A16_TYPELESS:
    case DXGI_FORMAT_R32G32_TYPELESS:
    case DXGI_FORMAT_R32G8X24_TYPELESS:
    case DXGI_FORMAT_R10G10B10A2_TYPELESS:
    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
    case DXGI_FORMAT_R16G16_TYPELESS:
    case DXGI_FORMAT_R32_TYPELESS:
    case DXGI_FORMAT_R8G8_TYPELESS:
    case DXGI_FORMAT_R16_TYPELESS:
    case DXGI_FORMAT_R8_TYPELESS:
    case DXGI_FORMAT_BC1_TYPELESS:
    case DXGI_FORMAT_BC2_TYPELESS:
    case DXGI_FORMAT_BC3_TYPELESS:
    case DXGI_FORMAT_BC4_TYPELESS:
    case DXGI_FORMAT_BC5_TYPELESS:
    case DXGI_FORMAT_B8G8R8A8_TYPELESS:
    case DXGI_FORMAT_B8G8R8X8_TYPELESS:
    case DXGI_FORMAT_BC6H_TYPELESS:
    case DXGI_FORMAT_BC7_TYPELESS:
    case DXGI_FORMAT_R24G8_TYPELESS:
    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
    case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
    case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
        return DXGI_FORMAT_UNKNOWN;

    default:
        return DXGI_FORMAT_R8G8B8A8_UNORM;
    }
}

/**
 * Convert between DXGI formats.
 *
 */
HRESULT
ConvertFormat(DXGI_FORMAT SrcFormat,
              void *SrcData,
              UINT SrcPitch,
              DXGI_FORMAT DstFormat,
              void *DstData,
              UINT DstPitch,
              UINT Width, UINT Height)
{
    HRESULT hr;

    DirectX::Image SrcImage;
    DirectX::Image DstImage;

    SrcImage.width = Width;
    SrcImage.height = Height;
    SrcImage.format = SrcFormat;
    SrcImage.rowPitch = SrcPitch;
    SrcImage.slicePitch = Height * SrcPitch;
    SrcImage.pixels = (uint8_t*)SrcData;

    DstImage.width = Width;
    DstImage.height = Height;
    DstImage.format = DstFormat;
    DstImage.rowPitch = DstPitch;
    DstImage.slicePitch = Height * DstPitch;
    DstImage.pixels = (uint8_t*)DstData;

    DirectX::Rect rect(0, 0, Width, Height);

    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    assert(SUCCEEDED(hr));
    if (FAILED(hr)) {
        return hr;
    }

    if (SrcFormat != DstFormat) {
        DirectX::ScratchImage ScratchImage;
        ScratchImage.Initialize2D(DstFormat, Width, Height, 1, 1);

        if (DirectX::IsCompressed(SrcFormat)) {
            hr = DirectX::Decompress(SrcImage, DstFormat, ScratchImage);
        } else {
            hr = DirectX::Convert(SrcImage, DstFormat, DirectX::TEX_FILTER_DEFAULT, 0.0f, ScratchImage);
        }

        if (SUCCEEDED(hr)) {
            hr = CopyRectangle(*ScratchImage.GetImage(0, 0, 0), rect, DstImage, DirectX::TEX_FILTER_DEFAULT, 0, 0);
        }
    } else {
        hr = CopyRectangle(SrcImage, rect, DstImage, DirectX::TEX_FILTER_DEFAULT, 0, 0);
    }

    return hr;
}

image::Image *
ConvertImage(DXGI_FORMAT SrcFormat,
             void *SrcData,
             UINT SrcPitch,
             UINT Width, UINT Height)
{

    DXGI_FORMAT DstFormat = ChooseConversionFormat(SrcFormat);
    if (DstFormat == DXGI_FORMAT_UNKNOWN) {
        return NULL;
    }

    image::Image *image = new image::Image(Width, Height, 4);
    if (!image) {
        return NULL;
    }
    assert(image->stride() > 0);

    HRESULT hr;
    hr = ConvertFormat(SrcFormat,
                       SrcData, SrcPitch,
                       DstFormat,
                       image->start(), image->stride(),
                       Width, Height);
    if (FAILED(hr)) {
        std::cerr << "warning: failed to convert from format " << SrcFormat << " to format " << DstFormat << "\n";
        delete image;
        image = NULL;
    }

    return image;
}

} /* namespace d3dstate */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: modulepreload.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: os $ $Date: 2001-11-14 13:17:47 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include "componentmodule.cxx"

<commit_msg>INTEGRATION: CWS ooo19126 (1.1.580); FILE MERGED 2005/09/05 12:59:55 rt 1.1.580.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: modulepreload.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:59:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "componentmodule.cxx"

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: browserview.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: fs $ $Date: 2001-05-30 13:44:49 $
 *
 *  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 _EXTENSIONS_PROPCTRLR_BROWSERVIEW_HXX_
#include "browserview.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_
#include "propertyeditor.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPHELPID_HRC_
#include "prophelpid.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPCONTROLLER_HXX_
#include "propcontroller.hxx"
#endif

//............................................................................
namespace pcr
{
//............................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;

    //========================================================================
    //= class OPropertyBrowserView
    //========================================================================
    DBG_NAME(OPropertyBrowserView)
    //------------------------------------------------------------------------
    OPropertyBrowserView::OPropertyBrowserView( const Reference< XMultiServiceFactory >& _rxORB,
                                 Window* _pParent, WinBits nBits)
                  :Window(_pParent, nBits | WB_3DLOOK)
                  ,m_pActiveController(NULL)
                  ,m_xORB(_rxORB)
                  ,m_nActivePage(0)
    {
        DBG_CTOR(OPropertyBrowserView,NULL);

        m_pPropBox = new OPropertyEditor( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        m_pPropBox->Show();
    }

    //------------------------------------------------------------------------
    OPropertyBrowserView::OPropertyBrowserView( const Reference< XMultiServiceFactory >& _rxORB,
                                 Window* _pParent, const ResId& rId)
                  :Window(_pParent, rId)
                  ,m_pActiveController(NULL)
                  ,m_xORB(_rxORB)
                  ,m_nActivePage(0)
    {
        DBG_CTOR(OPropertyBrowserView,NULL);

        m_pPropBox = new OPropertyEditor( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetPosSizePixel(Point(0,0), aSize);
        m_pPropBox->Show();
    }

    //------------------------------------------------------------------------
    IMPL_LINK(OPropertyBrowserView, OnPageActivation, void*, EMPTYARG)
    {
        m_nActivePage = m_pPropBox->GetCurPage();
        if (m_aPageActivationHandler.IsSet())
            m_aPageActivationHandler.Call(NULL);
        return 0L;
    }

    //------------------------------------------------------------------------
    OPropertyBrowserView::~OPropertyBrowserView()
    {
        if(m_pPropBox)
        {
            sal_uInt16 nTmpPage = m_pPropBox->GetCurPage();
            if (nTmpPage)
                m_nActivePage = nTmpPage;
            delete m_pPropBox;
        }
        if (m_pActiveController)
            m_pActiveController->release();
        m_pActiveController = NULL;

        m_xORB = NULL;

        DBG_DTOR(OPropertyBrowserView, NULL);
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::activatePage(sal_uInt16 _nPage)
    {
        m_nActivePage = _nPage;
        getPropertyBox()->SetPage(m_nActivePage);
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::setActiveController(OPropertyBrowserController* _pController)
    {
        if (_pController != m_pActiveController)
        {
            if (m_pActiveController) m_pActiveController->release();
            m_pActiveController = _pController;
            if (m_pActiveController) m_pActiveController->acquire();
        }
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::GetFocus()
    {
        if (m_pPropBox)
            m_pPropBox->GrabFocus();
        else
            Window::GetFocus();
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::Resize()
    {
        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetSizePixel(aSize);
    }

//............................................................................
} // namespace pcr
//............................................................................

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.3  2001/02/19 14:08:31  fs
 *  #84041# infrastructure for activating pages from outside
 *
 *  Revision 1.2  2001/01/18 14:45:10  rt
 *  #65293# semicolon removed
 *
 *  Revision 1.1  2001/01/12 11:26:10  fs
 *  initial checkin - outsourced the form property browser
 *
 *
 *  Revision 1.0 08.01.01 11:05:54  fs
 ************************************************************************/

<commit_msg>#102058# use auto_ptr in dtor<commit_after>/*************************************************************************
 *
 *  $RCSfile: browserview.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: oj $ $Date: 2002-08-06 08:13:10 $
 *
 *  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 _EXTENSIONS_PROPCTRLR_BROWSERVIEW_HXX_
#include "browserview.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_
#include "propertyeditor.hxx"
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPHELPID_HRC_
#include "prophelpid.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _EXTENSIONS_PROPCTRLR_PROPCONTROLLER_HXX_
#include "propcontroller.hxx"
#endif
#include <memory>

//............................................................................
namespace pcr
{
//............................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;

    //========================================================================
    //= class OPropertyBrowserView
    //========================================================================
    DBG_NAME(OPropertyBrowserView)
    //------------------------------------------------------------------------
    OPropertyBrowserView::OPropertyBrowserView( const Reference< XMultiServiceFactory >& _rxORB,
                                 Window* _pParent, WinBits nBits)
                  :Window(_pParent, nBits | WB_3DLOOK)
                  ,m_pActiveController(NULL)
                  ,m_xORB(_rxORB)
                  ,m_nActivePage(0)
    {
        DBG_CTOR(OPropertyBrowserView,NULL);

        m_pPropBox = new OPropertyEditor( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        m_pPropBox->Show();
    }

    //------------------------------------------------------------------------
    OPropertyBrowserView::OPropertyBrowserView( const Reference< XMultiServiceFactory >& _rxORB,
                                 Window* _pParent, const ResId& rId)
                  :Window(_pParent, rId)
                  ,m_pActiveController(NULL)
                  ,m_xORB(_rxORB)
                  ,m_nActivePage(0)
    {
        DBG_CTOR(OPropertyBrowserView,NULL);

        m_pPropBox = new OPropertyEditor( this );
        m_pPropBox->SetHelpId(HID_FM_PROPDLG_TABCTR);
        m_pPropBox->setPageActivationHandler(LINK(this, OPropertyBrowserView, OnPageActivation));

        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetPosSizePixel(Point(0,0), aSize);
        m_pPropBox->Show();
    }

    //------------------------------------------------------------------------
    IMPL_LINK(OPropertyBrowserView, OnPageActivation, void*, EMPTYARG)
    {
        m_nActivePage = m_pPropBox->GetCurPage();
        if (m_aPageActivationHandler.IsSet())
            m_aPageActivationHandler.Call(NULL);
        return 0L;
    }

    //------------------------------------------------------------------------
    OPropertyBrowserView::~OPropertyBrowserView()
    {
        if(m_pPropBox)
        {
            sal_uInt16 nTmpPage = m_pPropBox->GetCurPage();
            if (nTmpPage)
                m_nActivePage = nTmpPage;
            ::std::auto_ptr<Window> aTemp(m_pPropBox);
            m_pPropBox = NULL;
        }
        if (m_pActiveController)
            m_pActiveController->release();
        m_pActiveController = NULL;

        m_xORB = NULL;

        DBG_DTOR(OPropertyBrowserView, NULL);
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::activatePage(sal_uInt16 _nPage)
    {
        m_nActivePage = _nPage;
        getPropertyBox()->SetPage(m_nActivePage);
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::setActiveController(OPropertyBrowserController* _pController)
    {
        if (_pController != m_pActiveController)
        {
            if (m_pActiveController) m_pActiveController->release();
            m_pActiveController = _pController;
            if (m_pActiveController) m_pActiveController->acquire();
        }
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::GetFocus()
    {
        if (m_pPropBox)
            m_pPropBox->GrabFocus();
        else
            Window::GetFocus();
    }

    //------------------------------------------------------------------------
    void OPropertyBrowserView::Resize()
    {
        Size aSize = GetOutputSizePixel();
        m_pPropBox->SetSizePixel(aSize);
    }

//............................................................................
} // namespace pcr
//............................................................................

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.4  2001/05/30 13:44:49  fs
 *  #86838# forward the GetFocus event to the property box
 *
 *  Revision 1.3  2001/02/19 14:08:31  fs
 *  #84041# infrastructure for activating pages from outside
 *
 *  Revision 1.2  2001/01/18 14:45:10  rt
 *  #65293# semicolon removed
 *
 *  Revision 1.1  2001/01/12 11:26:10  fs
 *  initial checkin - outsourced the form property browser
 *
 *
 *  Revision 1.0 08.01.01 11:05:54  fs
 ************************************************************************/

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: download.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2007-07-31 15:55:50 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#if defined WNT
#pragma warning(push, 1) /* disable warnings within system headers */
#include <curl/curl.h>
#pragma warning(pop)
#else
#include <curl/curl.h>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#include "download.hxx"

namespace beans = com::sun::star::beans ;
namespace container = com::sun::star::container ;
namespace lang = com::sun::star::lang ;
namespace uno = com::sun::star::uno ;

#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))

struct OutData
{
    rtl::Reference< DownloadInteractionHandler >Handler;
    rtl::OUString   File;
    rtl::OUString   DestinationDir;
    oslFileHandle   FileHandle;
    sal_uInt64      Offset;
    osl::Condition& StopCondition;
    CURL *curl;

    OutData(osl::Condition& rCondition) : FileHandle(NULL), Offset(0), StopCondition(rCondition), curl(NULL) {};
};

//------------------------------------------------------------------------------

static inline rtl::OString
getStringValue(const uno::Reference< container::XNameAccess >& xNameAccess, const rtl::OUString& aName)
{
    rtl::OString aRet;

    OSL_ASSERT(xNameAccess->hasByName(aName));
    uno::Any aValue = xNameAccess->getByName(aName);

    return rtl::OUStringToOString(aValue.get<rtl::OUString>(), RTL_TEXTENCODING_UTF8);
}

//------------------------------------------------------------------------------

static inline sal_Int32
getInt32Value(const uno::Reference< container::XNameAccess >& xNameAccess, const rtl::OUString& aName)
{
    OSL_ASSERT(xNameAccess->hasByName(aName));
    uno::Any aValue = xNameAccess->getByName(aName);

    return aValue.get<sal_Int32>();
}

//------------------------------------------------------------------------------

static size_t
write_function( void *ptr, size_t size, size_t nmemb, void *stream )
{
    OutData *out = reinterpret_cast < OutData * > (stream);

    if( NULL == out->FileHandle )
    {
        char * effective_url;
        curl_easy_getinfo(out->curl, CURLINFO_EFFECTIVE_URL, &effective_url);

        double fDownloadSize;
        curl_easy_getinfo(out->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fDownloadSize);

        rtl::OString aURL(effective_url);

        // ensure no trailing '/'
        sal_Int32 nLen = aURL.getLength();
        while( (nLen > 0) && ('/' == aURL[nLen-1]) )
            aURL = aURL.copy(0, --nLen);

        // extract file name last '/'
        sal_Int32 nIndex = aURL.lastIndexOf('/');
        if( nIndex > 0 )
        {
            out->File = out->DestinationDir + rtl::OStringToOUString(aURL.copy(nIndex), RTL_TEXTENCODING_UTF8);

            oslFileError rc;

            // Give the user an overwrite warning if the target file exists
            const sal_Int32 openFlags = osl_File_OpenFlag_Write | osl_File_OpenFlag_Create;
            do
            {
                rc = osl_openFile(out->File.pData, &out->FileHandle, openFlags);

                if( osl_File_E_EXIST == rc && ! out->Handler->downloadTargetExists(out->File) )
                {
                    out->StopCondition.set();
                    break;
                }

            } while( osl_File_E_EXIST == rc );

            if( osl_File_E_None == rc )
                out->Handler->downloadStarted(out->File, (sal_Int64) fDownloadSize);
        }
    }

    sal_uInt64 nBytesWritten = 0;

    if( NULL != out->FileHandle )
        osl_writeFile(out->FileHandle, ptr, size * nmemb, &nBytesWritten);

    return (size_t) nBytesWritten;
}

//------------------------------------------------------------------------------

static int
progress_callback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow )
{
    (void) ultotal;
    (void) ulnow;

    OutData *out = reinterpret_cast < OutData * > (clientp);

    OSL_ASSERT( out );

    if( ! out->StopCondition.check() )
    {
        double fPercent = (dlnow + out->Offset) * 100 / (dltotal + out->Offset);
        if( fPercent < 0 )
            fPercent = 0;

        // Do not report progress for redirection replies
        long nCode;
        curl_easy_getinfo(out->curl, CURLINFO_RESPONSE_CODE, &nCode);
        if( (nCode != 302) && (nCode != 303) )
            out->Handler->downloadProgressAt((sal_Int8)fPercent);

        return 0;
    }

    // If stop condition is set, return non 0 value to abort
    return -1;
}

//------------------------------------------------------------------------------

void
Download::getProxyForURL(const rtl::OUString& rURL, rtl::OString& rHost, sal_Int32& rPort) const
{
    if( !m_xContext.is() )
        throw uno::RuntimeException(
            UNISTRING( "Download: empty component context" ),
            uno::Reference< uno::XInterface >() );

    uno::Reference< lang::XMultiComponentFactory > xServiceManager(m_xContext->getServiceManager());

    if( !xServiceManager.is() )
        throw uno::RuntimeException(
            UNISTRING( "Download: unable to obtain service manager from component context" ),
            uno::Reference< uno::XInterface >() );

    uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
        xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.configuration.ConfigurationProvider" ), m_xContext ),
        uno::UNO_QUERY_THROW);

    beans::PropertyValue aProperty;
    aProperty.Name  = UNISTRING( "nodepath" );
    aProperty.Value = uno::makeAny( UNISTRING("org.openoffice.Inet/Settings") );

    uno::Sequence< uno::Any > aArgumentList( 1 );
    aArgumentList[0] = uno::makeAny( aProperty );

    uno::Reference< container::XNameAccess > xNameAccess(
        xConfigProvider->createInstanceWithArguments(
            UNISTRING("com.sun.star.configuration.ConfigurationAccess"), aArgumentList ),
        uno::UNO_QUERY_THROW );

    OSL_ASSERT(xNameAccess->hasByName(UNISTRING("ooInetProxyType")));
    uno::Any aValue = xNameAccess->getByName(UNISTRING("ooInetProxyType"));

    sal_Int32 nProxyType = aValue.get< sal_Int32 >();
    if( 0 != nProxyType ) // type 0 means "direct connection to the internet
    {
        if( rURL.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("http:")) )
        {
            rHost = getStringValue(xNameAccess, UNISTRING("ooInetHTTPProxyName"));
            rPort = getInt32Value(xNameAccess, UNISTRING("ooInetHTTPProxyPort"));
        }
        else if( rURL.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("ftp:")) )
        {
            rHost = getStringValue(xNameAccess, UNISTRING("ooInetFTPProxyName"));
            rPort = getInt32Value(xNameAccess, UNISTRING("ooInetFTPProxyPort"));
        }
    }
}

//------------------------------------------------------------------------------

bool curl_run(const rtl::OUString& rURL, OutData& out, const rtl::OString& aProxyHost, sal_Int32 nProxyPort)
{
    /* Need to investigate further whether it is necessary to call
     * curl_global_init or not - leave it for now (as the ftp UCB content
     * provider does as well).
     */

    CURL * pCURL = curl_easy_init();
    bool ret = false;

    if( NULL != pCURL )
    {
        out.curl = pCURL;

        rtl::OString aURL(rtl::OUStringToOString(rURL, RTL_TEXTENCODING_UTF8));
        curl_easy_setopt(pCURL, CURLOPT_URL, aURL.getStr());

        // enable redirection
        curl_easy_setopt(pCURL, CURLOPT_FOLLOWLOCATION, 1);

        // write function
        curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, &out);
        curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, &write_function);

        // progress handler - Condition::check unfortunatly is not defined const
        curl_easy_setopt(pCURL, CURLOPT_NOPROGRESS, 0);
        curl_easy_setopt(pCURL, CURLOPT_PROGRESSFUNCTION, &progress_callback);
        curl_easy_setopt(pCURL, CURLOPT_PROGRESSDATA, &out);

        // proxy
        curl_easy_setopt(pCURL, CURLOPT_PROXY, aProxyHost.getStr());
        curl_easy_setopt(pCURL, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
        if( -1 != nProxyPort )
            curl_easy_setopt(pCURL, CURLOPT_PROXYPORT, nProxyPort);

        // ToDo: SSL support

        if( out.Offset > 0 )
        {
            // curl_off_t offset = nOffset; libcurl seems to be compiled with large
            // file support (and we not) ..
            sal_Int64 offset = (sal_Int64) out.Offset;
            curl_easy_setopt(pCURL, CURLOPT_RESUME_FROM_LARGE, offset);
        }

        CURLcode cc = curl_easy_perform(pCURL);

        if( CURLE_OK == cc )
        {
            out.Handler->downloadFinished(out.File);
            ret = true;
        }

        // Avoid target file being removed
        else if( (CURLE_ABORTED_BY_CALLBACK == cc) || out.StopCondition.check() )
            ret = true;

        // Only report errors when not stopped
        else
        {
            rtl::OString aMessage(RTL_CONSTASCII_STRINGPARAM("Unknown error"));

            const char * error_message = curl_easy_strerror(cc);
            if( NULL != error_message )
                aMessage = error_message;

            out.Handler->downloadStalled( rtl::OStringToOUString(aMessage, RTL_TEXTENCODING_UTF8) );
        }

        curl_easy_cleanup(pCURL);
    }

    return ret;
}

//------------------------------------------------------------------------------

bool
Download::start(const rtl::OUString& rURL, const rtl::OUString& rFile, const rtl::OUString& rDestinationDir)
{
    OSL_ASSERT( m_aHandler.is() );

    OutData out(m_aCondition);

    out.File = rFile;
    out.DestinationDir = rDestinationDir;
    out.Handler = m_aHandler;

    if( rFile.getLength() > 0 )
    {
        oslFileError rc = osl_openFile(rFile.pData, &out.FileHandle, osl_File_OpenFlag_Write);

        if( osl_File_E_None == rc )
        {
            // Set file pointer to the end of the file on resume
            if( osl_File_E_None == osl_setFilePos(out.FileHandle, osl_Pos_End, 0) )
            {
                osl_getFilePos(out.FileHandle, &out.Offset);
            }
        }
        else if( osl_File_E_NOENT == rc ) // file has been deleted meanwhile ..
            out.File = rtl::OUString();
    }

    rtl::OString aProxyHost;
    sal_Int32    nProxyPort = -1;
    getProxyForURL(rURL, aProxyHost, nProxyPort);

    bool ret = curl_run(rURL, out, aProxyHost, nProxyPort);

    if( NULL != out.FileHandle )
    {
        osl_syncFile(out.FileHandle);
        osl_closeFile(out.FileHandle);

        if( ! ret )
            osl_removeFile(out.File.pData);
    }

    m_aCondition.reset();
    return ret;
}

//------------------------------------------------------------------------------

void
Download::stop()
{
    m_aCondition.set();
}
<commit_msg>INTEGRATION: CWS updchk07b_SRC680 (1.3.16); FILE MERGED 2007/08/29 10:50:22 obr 1.3.16.1: #i81081# Any::get<> throws an exception when empty<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: download.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2007-08-30 15:46:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#if defined WNT
#pragma warning(push, 1) /* disable warnings within system headers */
#include <curl/curl.h>
#pragma warning(pop)
#else
#include <curl/curl.h>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#include "download.hxx"

namespace beans = com::sun::star::beans ;
namespace container = com::sun::star::container ;
namespace lang = com::sun::star::lang ;
namespace uno = com::sun::star::uno ;

#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))

struct OutData
{
    rtl::Reference< DownloadInteractionHandler >Handler;
    rtl::OUString   File;
    rtl::OUString   DestinationDir;
    oslFileHandle   FileHandle;
    sal_uInt64      Offset;
    osl::Condition& StopCondition;
    CURL *curl;

    OutData(osl::Condition& rCondition) : FileHandle(NULL), Offset(0), StopCondition(rCondition), curl(NULL) {};
};

//------------------------------------------------------------------------------

static inline rtl::OString
getStringValue(const uno::Reference< container::XNameAccess >& xNameAccess, const rtl::OUString& aName)
{
    rtl::OString aRet;

    OSL_ASSERT(xNameAccess->hasByName(aName));
    uno::Any aValue = xNameAccess->getByName(aName);

    return rtl::OUStringToOString(aValue.get<rtl::OUString>(), RTL_TEXTENCODING_UTF8);
}

//------------------------------------------------------------------------------

static inline sal_Int32
getInt32Value(const uno::Reference< container::XNameAccess >& xNameAccess,
                    const rtl::OUString& aName, sal_Int32 nDefault=-1)
{
    OSL_ASSERT(xNameAccess->hasByName(aName));
    uno::Any aValue = xNameAccess->getByName(aName);

    sal_Int32 n=nDefault;
    aValue >>= n;
    return n;
}

//------------------------------------------------------------------------------

static size_t
write_function( void *ptr, size_t size, size_t nmemb, void *stream )
{
    OutData *out = reinterpret_cast < OutData * > (stream);

    if( NULL == out->FileHandle )
    {
        char * effective_url;
        curl_easy_getinfo(out->curl, CURLINFO_EFFECTIVE_URL, &effective_url);

        double fDownloadSize;
        curl_easy_getinfo(out->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fDownloadSize);

        rtl::OString aURL(effective_url);

        // ensure no trailing '/'
        sal_Int32 nLen = aURL.getLength();
        while( (nLen > 0) && ('/' == aURL[nLen-1]) )
            aURL = aURL.copy(0, --nLen);

        // extract file name last '/'
        sal_Int32 nIndex = aURL.lastIndexOf('/');
        if( nIndex > 0 )
        {
            out->File = out->DestinationDir + rtl::OStringToOUString(aURL.copy(nIndex), RTL_TEXTENCODING_UTF8);

            oslFileError rc;

            // Give the user an overwrite warning if the target file exists
            const sal_Int32 openFlags = osl_File_OpenFlag_Write | osl_File_OpenFlag_Create;
            do
            {
                rc = osl_openFile(out->File.pData, &out->FileHandle, openFlags);

                if( osl_File_E_EXIST == rc && ! out->Handler->downloadTargetExists(out->File) )
                {
                    out->StopCondition.set();
                    break;
                }

            } while( osl_File_E_EXIST == rc );

            if( osl_File_E_None == rc )
                out->Handler->downloadStarted(out->File, (sal_Int64) fDownloadSize);
        }
    }

    sal_uInt64 nBytesWritten = 0;

    if( NULL != out->FileHandle )
        osl_writeFile(out->FileHandle, ptr, size * nmemb, &nBytesWritten);

    return (size_t) nBytesWritten;
}

//------------------------------------------------------------------------------

static int
progress_callback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow )
{
    (void) ultotal;
    (void) ulnow;

    OutData *out = reinterpret_cast < OutData * > (clientp);

    OSL_ASSERT( out );

    if( ! out->StopCondition.check() )
    {
        double fPercent = (dlnow + out->Offset) * 100 / (dltotal + out->Offset);
        if( fPercent < 0 )
            fPercent = 0;

        // Do not report progress for redirection replies
        long nCode;
        curl_easy_getinfo(out->curl, CURLINFO_RESPONSE_CODE, &nCode);
        if( (nCode != 302) && (nCode != 303) )
            out->Handler->downloadProgressAt((sal_Int8)fPercent);

        return 0;
    }

    // If stop condition is set, return non 0 value to abort
    return -1;
}

//------------------------------------------------------------------------------

void
Download::getProxyForURL(const rtl::OUString& rURL, rtl::OString& rHost, sal_Int32& rPort) const
{
    if( !m_xContext.is() )
        throw uno::RuntimeException(
            UNISTRING( "Download: empty component context" ),
            uno::Reference< uno::XInterface >() );

    uno::Reference< lang::XMultiComponentFactory > xServiceManager(m_xContext->getServiceManager());

    if( !xServiceManager.is() )
        throw uno::RuntimeException(
            UNISTRING( "Download: unable to obtain service manager from component context" ),
            uno::Reference< uno::XInterface >() );

    uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
        xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.configuration.ConfigurationProvider" ), m_xContext ),
        uno::UNO_QUERY_THROW);

    beans::PropertyValue aProperty;
    aProperty.Name  = UNISTRING( "nodepath" );
    aProperty.Value = uno::makeAny( UNISTRING("org.openoffice.Inet/Settings") );

    uno::Sequence< uno::Any > aArgumentList( 1 );
    aArgumentList[0] = uno::makeAny( aProperty );

    uno::Reference< container::XNameAccess > xNameAccess(
        xConfigProvider->createInstanceWithArguments(
            UNISTRING("com.sun.star.configuration.ConfigurationAccess"), aArgumentList ),
        uno::UNO_QUERY_THROW );

    OSL_ASSERT(xNameAccess->hasByName(UNISTRING("ooInetProxyType")));
    uno::Any aValue = xNameAccess->getByName(UNISTRING("ooInetProxyType"));

    sal_Int32 nProxyType = aValue.get< sal_Int32 >();
    if( 0 != nProxyType ) // type 0 means "direct connection to the internet
    {
        if( rURL.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("http:")) )
        {
            rHost = getStringValue(xNameAccess, UNISTRING("ooInetHTTPProxyName"));
            rPort = getInt32Value(xNameAccess, UNISTRING("ooInetHTTPProxyPort"));
        }
        else if( rURL.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("ftp:")) )
        {
            rHost = getStringValue(xNameAccess, UNISTRING("ooInetFTPProxyName"));
            rPort = getInt32Value(xNameAccess, UNISTRING("ooInetFTPProxyPort"));
        }
    }
}

//------------------------------------------------------------------------------

bool curl_run(const rtl::OUString& rURL, OutData& out, const rtl::OString& aProxyHost, sal_Int32 nProxyPort)
{
    /* Need to investigate further whether it is necessary to call
     * curl_global_init or not - leave it for now (as the ftp UCB content
     * provider does as well).
     */

    CURL * pCURL = curl_easy_init();
    bool ret = false;

    if( NULL != pCURL )
    {
        out.curl = pCURL;

        rtl::OString aURL(rtl::OUStringToOString(rURL, RTL_TEXTENCODING_UTF8));
        curl_easy_setopt(pCURL, CURLOPT_URL, aURL.getStr());

        // enable redirection
        curl_easy_setopt(pCURL, CURLOPT_FOLLOWLOCATION, 1);

        // write function
        curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, &out);
        curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, &write_function);

        // progress handler - Condition::check unfortunatly is not defined const
        curl_easy_setopt(pCURL, CURLOPT_NOPROGRESS, 0);
        curl_easy_setopt(pCURL, CURLOPT_PROGRESSFUNCTION, &progress_callback);
        curl_easy_setopt(pCURL, CURLOPT_PROGRESSDATA, &out);

        // proxy
        curl_easy_setopt(pCURL, CURLOPT_PROXY, aProxyHost.getStr());
        curl_easy_setopt(pCURL, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
        if( -1 != nProxyPort )
            curl_easy_setopt(pCURL, CURLOPT_PROXYPORT, nProxyPort);

        // ToDo: SSL support

        if( out.Offset > 0 )
        {
            // curl_off_t offset = nOffset; libcurl seems to be compiled with large
            // file support (and we not) ..
            sal_Int64 offset = (sal_Int64) out.Offset;
            curl_easy_setopt(pCURL, CURLOPT_RESUME_FROM_LARGE, offset);
        }

        CURLcode cc = curl_easy_perform(pCURL);

        if( CURLE_OK == cc )
        {
            out.Handler->downloadFinished(out.File);
            ret = true;
        }

        // Avoid target file being removed
        else if( (CURLE_ABORTED_BY_CALLBACK == cc) || out.StopCondition.check() )
            ret = true;

        // Only report errors when not stopped
        else
        {
            rtl::OString aMessage(RTL_CONSTASCII_STRINGPARAM("Unknown error"));

            const char * error_message = curl_easy_strerror(cc);
            if( NULL != error_message )
                aMessage = error_message;

            out.Handler->downloadStalled( rtl::OStringToOUString(aMessage, RTL_TEXTENCODING_UTF8) );
        }

        curl_easy_cleanup(pCURL);
    }

    return ret;
}

//------------------------------------------------------------------------------

bool
Download::start(const rtl::OUString& rURL, const rtl::OUString& rFile, const rtl::OUString& rDestinationDir)
{
    OSL_ASSERT( m_aHandler.is() );

    OutData out(m_aCondition);

    out.File = rFile;
    out.DestinationDir = rDestinationDir;
    out.Handler = m_aHandler;

    if( rFile.getLength() > 0 )
    {
        oslFileError rc = osl_openFile(rFile.pData, &out.FileHandle, osl_File_OpenFlag_Write);

        if( osl_File_E_None == rc )
        {
            // Set file pointer to the end of the file on resume
            if( osl_File_E_None == osl_setFilePos(out.FileHandle, osl_Pos_End, 0) )
            {
                osl_getFilePos(out.FileHandle, &out.Offset);
            }
        }
        else if( osl_File_E_NOENT == rc ) // file has been deleted meanwhile ..
            out.File = rtl::OUString();
    }

    rtl::OString aProxyHost;
    sal_Int32    nProxyPort = -1;
    getProxyForURL(rURL, aProxyHost, nProxyPort);

    bool ret = curl_run(rURL, out, aProxyHost, nProxyPort);

    if( NULL != out.FileHandle )
    {
        osl_syncFile(out.FileHandle);
        osl_closeFile(out.FileHandle);

        if( ! ret )
            osl_removeFile(out.File.pData);
    }

    m_aCondition.reset();
    return ret;
}

//------------------------------------------------------------------------------

void
Download::stop()
{
    m_aCondition.set();
}
<|endoftext|>


<commit_before>/* ffpack_rankprofiles.inl
 * Copyright (C) 2015 FFLAS-FFACK group
 *
 * Written by Clement Pernet <Clement.Pernet@imag.fr>
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

#ifndef __FFLASFFPACK_ffpack_rank_profiles_INL
#define __FFLASFFPACK_ffpack_rank_profiles_INL

namespace FFPACK{
    template <class Field>
    inline size_t RowRankProfile (const Field& F, const size_t M, const size_t N,
                                  typename Field::Element_ptr A, const size_t lda,
                                  size_t* &rkprofile,
                                  const FFPACK_LU_TAG LuTag){

        size_t *P = FFLAS::fflas_new<size_t>((LuTag==FfpackSlabRecursive)?N:M);
        size_t *Q = FFLAS::fflas_new<size_t>((LuTag==FfpackSlabRecursive)?M:N);
        size_t R;

        if (LuTag == FfpackSlabRecursive){
            R = LUdivine (F, FFLAS::FflasNonUnit, FFLAS::FflasNoTrans, M, N, A, lda, P, Q);
            std::swap(P,Q);
        } else
            R = PLUQ (F, FFLAS::FflasNonUnit, M, N, A, lda, P, Q);

        rkprofile = FFLAS::fflas_new<size_t> (R);

        RankProfileFromLU (P, M, R, rkprofile, LuTag);

        FFLAS::fflas_delete (Q);
        FFLAS::fflas_delete (P);
        return R;
    }
    template <class Field>
    inline size_t ColumnRankProfile (const Field& F, const size_t M, const size_t N,
                                     typename Field::Element_ptr A, const size_t lda,
                                     size_t* &rkprofile,
                                     const FFPACK_LU_TAG LuTag){

        size_t *P = FFLAS::fflas_new<size_t>(M);
        size_t *Q = FFLAS::fflas_new<size_t>(N);
        size_t R;

        if (LuTag == FfpackSlabRecursive){
            R = LUdivine (F, FFLAS::FflasNonUnit, FFLAS::FflasTrans, M, N, A, lda, P, Q);
        } else
            R = PLUQ (F, FFLAS::FflasNonUnit, M, N, A, lda, P, Q);

        rkprofile = FFLAS::fflas_new<size_t> (R);

        RankProfileFromLU (Q, N, R, rkprofile, LuTag);

        FFLAS::fflas_delete (P);
        FFLAS::fflas_delete (Q);
        return R;
    }

    inline void RankProfileFromLU (const size_t* Q, const size_t N, const size_t R,
                                   size_t* rkprofile, const FFPACK_LU_TAG LuTag){

        if (LuTag == FfpackSlabRecursive)
            std::copy(Q, Q+R, rkprofile);
        else {
            size_t * RP = FFLAS::fflas_new<size_t>(N);
            for (size_t i=0;i < N; ++i)
                RP [i] = i;
            for (size_t i=0; i<N; ++i)
                if (Q[i] != i)
                    std::swap (RP [i], RP [Q [i]]);

            std::copy(RP, RP+R, rkprofile);
            std::sort (rkprofile, rkprofile + R);
            FFLAS::fflas_delete(RP);
        }
    }

    inline size_t LeadingSubmatrixRankProfiles (const size_t M, const size_t N, const size_t R,
                                                const size_t LSm, const size_t LSn,
                                                const size_t* P, const size_t* Q,
                                                size_t* RRP, size_t* CRP){
        size_t LSr=0; // rank of the LSm x LSn leading submatrix

        size_t* MathP = FFLAS::fflas_new<size_t>(M);
        size_t* MathQ = FFLAS::fflas_new<size_t>(N);

        LAPACKPerm2MathPerm (MathP, P, M);
        LAPACKPerm2MathPerm (MathQ, Q, N);
        for (size_t i = 0; i < R; i++)
            if (MathP[i] < LSm && MathQ[i] < LSn){
                RRP [LSr] = MathP[i];
                CRP [LSr] = MathQ[i];
                LSr++;
            }
        std::sort (RRP, RRP+LSr);
        std::sort (CRP, CRP+LSr);
        FFLAS::fflas_delete(MathP);
        FFLAS::fflas_delete(MathQ);
        return LSr;

    }

    template <class Field>
    size_t RowRankProfileSubmatrixIndices (const Field& F,
                                           const size_t M, const size_t N,
                                           typename Field::Element_ptr A,
                                           const size_t lda,
                                           size_t*& rowindices,
                                           size_t*& colindices,
                                           size_t& R)
    {
        size_t *P = FFLAS::fflas_new<size_t>(N);
        size_t *Q = FFLAS::fflas_new<size_t>(M);

        R = LUdivine (F, FFLAS::FflasNonUnit, FFLAS::FflasNoTrans, M, N, A, lda, P, Q);
        rowindices = FFLAS::fflas_new<size_t>(M);
        colindices = FFLAS::fflas_new<size_t>(N);
        for (size_t i=0; i<R; ++i){
            rowindices [i] = Q [i];
        }
        for (size_t i=0; i<N; ++i)
            colindices [i] = i;
        size_t tmp;
        for (size_t i=0; i<R; ++i){
            if (i != P[i]){
                tmp = colindices[i];
                colindices[i] = colindices[P[i]];
                colindices[P[i]] = tmp;
            }
        }

        FFLAS::fflas_delete( P);
        FFLAS::fflas_delete( Q);

        return R;
    }

    template <class Field>
    size_t ColRankProfileSubmatrixIndices (const Field& F,
                                           const size_t M, const size_t N,
                                           typename Field::Element_ptr A,
                                           const size_t lda,
                                           size_t*& rowindices,
                                           size_t*& colindices,
                                           size_t& R)
    {
        size_t *P = FFLAS::fflas_new<size_t>(M);
        size_t *Q = FFLAS::fflas_new<size_t>(N);

        R = LUdivine (F, FFLAS::FflasNonUnit, FFLAS::FflasTrans, M, N, A, lda, P, Q);
        rowindices = FFLAS::fflas_new<size_t>(M);
        colindices = FFLAS::fflas_new<size_t>(N);
        for (size_t i=0; i<R; ++i)
            colindices [i] = Q [i];

        for (size_t i=0; i<N; ++i)
            rowindices [i] = i;

        size_t tmp;
        for (size_t i=0; i<R; ++i){
            if (i != P[i]){
                tmp = rowindices[i];
                rowindices[i] = rowindices[P[i]];
                rowindices[P[i]] = tmp;
            }
        }
        FFLAS::fflas_delete( P);
        FFLAS::fflas_delete( Q);

        return R;
    }

    template <class Field>
    size_t RowRankProfileSubmatrix (const Field& F,
                                    const size_t M, const size_t N,
                                    typename Field::Element_ptr A,
                                    const size_t lda,
                                    typename Field::Element_ptr& X, size_t& R)
    {

        size_t * rowindices, * colindices;

        typename Field::Element_ptr A2 = FFLAS::fflas_new (F, M, N) ;
        FFLAS::fassign(F,M,N,A,lda,A2,N);

        RowRankProfileSubmatrixIndices (F, M, N, A2, N, rowindices, colindices, R);

        X = FFLAS::fflas_new (F, R, R);
        for (size_t i=0; i<R; ++i)
            for (size_t j=0; j<R; ++j)
                F.assign (*(X + i*R + j), *(A + rowindices[i]*lda + colindices[j]));
        FFLAS::fflas_delete (A2);
        FFLAS::fflas_delete( rowindices);
        FFLAS::fflas_delete( colindices);
        return R;
    }

    template <class Field>
    size_t ColRankProfileSubmatrix (const Field& F, const size_t M, const size_t N,
                                    typename Field::Element_ptr A, const size_t lda,
                                    typename Field::Element_ptr& X, size_t& R)
    {

        size_t * rowindices, * colindices;

        typename Field::Element_ptr A2 = FFLAS::fflas_new (F, M, N);
        FFLAS::fassign(F,M,N,A,lda,A2,N);

        ColRankProfileSubmatrixIndices (F, M, N, A2, N, rowindices, colindices, R);

        X = FFLAS::fflas_new (F, R, R);
        for (size_t i=0; i<R; ++i)
            for (size_t j=0; j<R; ++j)
                F.assign (*(X + i*R + j), *(A + rowindices[i]*lda + colindices[j]));
        FFLAS::fflas_delete (A2);
        FFLAS::fflas_delete( colindices);
        FFLAS::fflas_delete( rowindices);
        return R;
    }

    template <class Field>
    typename Field::Element_ptr
    LQUPtoInverseOfFullRankMinor( const Field& F, const size_t rank,
                                  typename Field::Element_ptr A_factors, const size_t lda,
                                  const size_t* QtPointer,
                                  typename Field::Element_ptr X, const size_t ldx)
    {

        // upper entries are okay, just need to move up bottom ones
        const size_t* srcRow = QtPointer;
        for (size_t row=0; row<rank; row++, srcRow++)
            if (*srcRow != row) {
                typename Field::Element_ptr oldRow = A_factors + (*srcRow) * lda;
                typename Field::Element_ptr newRow = A_factors + row * lda;
                for (size_t col=0; col<row; col++, oldRow++, newRow++)
                    F.assign(*newRow, *oldRow);
            }

        // X <- (Qt.L.Q)^(-1)
        //invL( F, rank, A_factors, lda, X, ldx);
        ftrtri (F, FFLAS::FflasLower, FFLAS::FflasUnit, rank, A_factors, lda);
        FFLAS::fassign(F,rank,rank,X,ldx,A_factors,lda);

        // X = U^-1.X
        ftrsm( F, FFLAS::FflasLeft, FFLAS::FflasUpper, FFLAS::FflasNoTrans,
               FFLAS::FflasNonUnit, rank, rank, F.one, A_factors, lda, X, ldx);

        return X;

    }

} // namespace FFPACK

#endif // __FFLASFFPACK_ffpack_rank_profiles_INL
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<commit_msg>Assign was used in the wrong direction. Solves issue #189 of LinBox.<commit_after>/* ffpack_rankprofiles.inl
 * Copyright (C) 2015 FFLAS-FFACK group
 *
 * Written by Clement Pernet <Clement.Pernet@imag.fr>
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

#ifndef __FFLASFFPACK_ffpack_rank_profiles_INL
#define __FFLASFFPACK_ffpack_rank_profiles_INL

namespace FFPACK{
    template <class Field>
    inline size_t RowRankProfile (const Field& F, const size_t M, const size_t N,
                                  typename Field::Element_ptr A, const size_t lda,
                                  size_t* &rkprofile,
                                  const FFPACK_LU_TAG LuTag){

        size_t *P = FFLAS::fflas_new<size_t>((LuTag==FfpackSlabRecursive)?N:M);
        size_t *Q = FFLAS::fflas_new<size_t>((LuTag==FfpackSlabRecursive)?M:N);
        size_t R;

        if (LuTag == FfpackSlabRecursive){
            R = LUdivine (F, FFLAS::FflasNonUnit, FFLAS::FflasNoTrans, M, N, A, lda, P, Q);
            std::swap(P,Q);
        } else
            R = PLUQ (F, FFLAS::FflasNonUnit, M, N, A, lda, P, Q);

        rkprofile = FFLAS::fflas_new<size_t> (R);

        RankProfileFromLU (P, M, R, rkprofile, LuTag);

        FFLAS::fflas_delete (Q);
        FFLAS::fflas_delete (P);
        return R;
    }
    template <class Field>
    inline size_t ColumnRankProfile (const Field& F, const size_t M, const size_t N,
                                     typename Field::Element_ptr A, const size_t lda,
                                     size_t* &rkprofile,
                                     const FFPACK_LU_TAG LuTag){

        size_t *P = FFLAS::fflas_new<size_t>(M);
        size_t *Q = FFLAS::fflas_new<size_t>(N);
        size_t R;

        if (LuTag == FfpackSlabRecursive){
            R = LUdivine (F, FFLAS::FflasNonUnit, FFLAS::FflasTrans, M, N, A, lda, P, Q);
        } else
            R = PLUQ (F, FFLAS::FflasNonUnit, M, N, A, lda, P, Q);

        rkprofile = FFLAS::fflas_new<size_t> (R);

        RankProfileFromLU (Q, N, R, rkprofile, LuTag);

        FFLAS::fflas_delete (P);
        FFLAS::fflas_delete (Q);
        return R;
    }

    inline void RankProfileFromLU (const size_t* Q, const size_t N, const size_t R,
                                   size_t* rkprofile, const FFPACK_LU_TAG LuTag){

        if (LuTag == FfpackSlabRecursive)
            std::copy(Q, Q+R, rkprofile);
        else {
            size_t * RP = FFLAS::fflas_new<size_t>(N);
            for (size_t i=0;i < N; ++i)
                RP [i] = i;
            for (size_t i=0; i<N; ++i)
                if (Q[i] != i)
                    std::swap (RP [i], RP [Q [i]]);

            std::copy(RP, RP+R, rkprofile);
            std::sort (rkprofile, rkprofile + R);
            FFLAS::fflas_delete(RP);
        }
    }

    inline size_t LeadingSubmatrixRankProfiles (const size_t M, const size_t N, const size_t R,
                                                const size_t LSm, const size_t LSn,
                                                const size_t* P, const size_t* Q,
                                                size_t* RRP, size_t* CRP){
        size_t LSr=0; // rank of the LSm x LSn leading submatrix

        size_t* MathP = FFLAS::fflas_new<size_t>(M);
        size_t* MathQ = FFLAS::fflas_new<size_t>(N);

        LAPACKPerm2MathPerm (MathP, P, M);
        LAPACKPerm2MathPerm (MathQ, Q, N);
        for (size_t i = 0; i < R; i++)
            if (MathP[i] < LSm && MathQ[i] < LSn){
                RRP [LSr] = MathP[i];
                CRP [LSr] = MathQ[i];
                LSr++;
            }
        std::sort (RRP, RRP+LSr);
        std::sort (CRP, CRP+LSr);
        FFLAS::fflas_delete(MathP);
        FFLAS::fflas_delete(MathQ);
        return LSr;

    }

    template <class Field>
    size_t RowRankProfileSubmatrixIndices (const Field& F,
                                           const size_t M, const size_t N,
                                           typename Field::Element_ptr A,
                                           const size_t lda,
                                           size_t*& rowindices,
                                           size_t*& colindices,
                                           size_t& R)
    {
        size_t *P = FFLAS::fflas_new<size_t>(N);
        size_t *Q = FFLAS::fflas_new<size_t>(M);

        R = LUdivine (F, FFLAS::FflasNonUnit, FFLAS::FflasNoTrans, M, N, A, lda, P, Q);
        rowindices = FFLAS::fflas_new<size_t>(M);
        colindices = FFLAS::fflas_new<size_t>(N);
        for (size_t i=0; i<R; ++i){
            rowindices [i] = Q [i];
        }
        for (size_t i=0; i<N; ++i)
            colindices [i] = i;
        size_t tmp;
        for (size_t i=0; i<R; ++i){
            if (i != P[i]){
                tmp = colindices[i];
                colindices[i] = colindices[P[i]];
                colindices[P[i]] = tmp;
            }
        }

        FFLAS::fflas_delete( P);
        FFLAS::fflas_delete( Q);

        return R;
    }

    template <class Field>
    size_t ColRankProfileSubmatrixIndices (const Field& F,
                                           const size_t M, const size_t N,
                                           typename Field::Element_ptr A,
                                           const size_t lda,
                                           size_t*& rowindices,
                                           size_t*& colindices,
                                           size_t& R)
    {
        size_t *P = FFLAS::fflas_new<size_t>(M);
        size_t *Q = FFLAS::fflas_new<size_t>(N);

        R = LUdivine (F, FFLAS::FflasNonUnit, FFLAS::FflasTrans, M, N, A, lda, P, Q);
        rowindices = FFLAS::fflas_new<size_t>(M);
        colindices = FFLAS::fflas_new<size_t>(N);
        for (size_t i=0; i<R; ++i)
            colindices [i] = Q [i];

        for (size_t i=0; i<N; ++i)
            rowindices [i] = i;

        size_t tmp;
        for (size_t i=0; i<R; ++i){
            if (i != P[i]){
                tmp = rowindices[i];
                rowindices[i] = rowindices[P[i]];
                rowindices[P[i]] = tmp;
            }
        }
        FFLAS::fflas_delete( P);
        FFLAS::fflas_delete( Q);

        return R;
    }

    template <class Field>
    size_t RowRankProfileSubmatrix (const Field& F,
                                    const size_t M, const size_t N,
                                    typename Field::Element_ptr A,
                                    const size_t lda,
                                    typename Field::Element_ptr& X, size_t& R)
    {

        size_t * rowindices, * colindices;

        typename Field::Element_ptr A2 = FFLAS::fflas_new (F, M, N) ;
        FFLAS::fassign(F,M,N,A,lda,A2,N);

        RowRankProfileSubmatrixIndices (F, M, N, A2, N, rowindices, colindices, R);

        X = FFLAS::fflas_new (F, R, R);
        for (size_t i=0; i<R; ++i)
            for (size_t j=0; j<R; ++j)
                F.assign (*(X + i*R + j), *(A + rowindices[i]*lda + colindices[j]));
        FFLAS::fflas_delete (A2);
        FFLAS::fflas_delete( rowindices);
        FFLAS::fflas_delete( colindices);
        return R;
    }

    template <class Field>
    size_t ColRankProfileSubmatrix (const Field& F, const size_t M, const size_t N,
                                    typename Field::Element_ptr A, const size_t lda,
                                    typename Field::Element_ptr& X, size_t& R)
    {

        size_t * rowindices, * colindices;

        typename Field::Element_ptr A2 = FFLAS::fflas_new (F, M, N);
        FFLAS::fassign(F,M,N,A,lda,A2,N);

        ColRankProfileSubmatrixIndices (F, M, N, A2, N, rowindices, colindices, R);

        X = FFLAS::fflas_new (F, R, R);
        for (size_t i=0; i<R; ++i)
            for (size_t j=0; j<R; ++j)
                F.assign (*(X + i*R + j), *(A + rowindices[i]*lda + colindices[j]));
        FFLAS::fflas_delete (A2);
        FFLAS::fflas_delete( colindices);
        FFLAS::fflas_delete( rowindices);
        return R;
    }

    template <class Field>
    typename Field::Element_ptr
    LQUPtoInverseOfFullRankMinor( const Field& F, const size_t rank,
                                  typename Field::Element_ptr A_factors, const size_t lda,
                                  const size_t* QtPointer,
                                  typename Field::Element_ptr X, const size_t ldx)
    {

        // upper entries are okay, just need to move up bottom ones
        const size_t* srcRow = QtPointer;
        for (size_t row=0; row<rank; row++, srcRow++)
            if (*srcRow != row) {
                typename Field::Element_ptr oldRow = A_factors + (*srcRow) * lda;
                typename Field::Element_ptr newRow = A_factors + row * lda;
                for (size_t col=0; col<row; col++, oldRow++, newRow++)
                    F.assign(*newRow, *oldRow);
            }

        // X <- (Qt.L.Q)^(-1)
        //invL( F, rank, A_factors, lda, X, ldx);
        ftrtri (F, FFLAS::FflasLower, FFLAS::FflasUnit, rank, A_factors, lda);
        FFLAS::fassign(F,rank,rank,A_factors,lda,X,ldx);

        // X = U^-1.X
        ftrsm( F, FFLAS::FflasLeft, FFLAS::FflasUpper, FFLAS::FflasNoTrans,
               FFLAS::FflasNonUnit, rank, rank, F.one, A_factors, lda, X, ldx);

        return X;

    }

} // namespace FFPACK

#endif // __FFLASFFPACK_ffpack_rank_profiles_INL
/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<|endoftext|>


<commit_before>/*
* Copyright 2014 Adam Hollidge <adam@anh.io>
*/

#include <SGP4.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <tuple>
#include <algorithm>
#include <utility>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

static inline std::istream& safeGetline(std::istream& is, std::string& t)
{
    t.clear();

    // The characters in the stream are read one-by-one using a std::streambuf.
    // That is faster than reading them one-by-one using the std::istream.
    // Code that uses streambuf this way must be guarded by a sentry object.
    // The sentry object performs various tasks,
    // such as thread synchronization and updating the stream state.

    std::istream::sentry se(is, true);
    std::streambuf* sb = is.rdbuf();

    for(;;) {
        int c = sb->sbumpc();
        switch (c) {
        case '\n':
            return is;
        case '\r':
            if(sb->sgetc() == '\n')
                sb->sbumpc();
            return is;
        case EOF:
            // Also handle the case when the last line has no line ending
            if(t.empty())
                is.setstate(std::ios::eofbit);
            return is;
        default:
            t += (char)c;
        }
    }
}

// Chronological TLE sort.
bool chron(const Tle& a, const Tle& b)
{
    return a.Epoch() < b.Epoch();
}

class Groundtrack
{
public:
    enum Format {
        GeoJSON
    };
    static const int max_prop_days = 7;

    Groundtrack(DateTime start_date,
                DateTime end_date,
                int dt,
                std::vector<Tle> tles)
                : start_date_(start_date),
                  end_date_(end_date),
                  dt_(TimeSpan(0, 0, dt)),
                  tles_(tles),
                  active_tle_(0),
                  max_terminal_propagation_(max_prop_days, 0, 0, 0, 0)
    {
        std::sort(tles_.begin(), tles_.end(), chron);

        // Roll back end date if it goes too far beyond
        // the last TLE.
        if (!tles_.empty()) {
            Tle last_tle = tles_.back();
            if ((end_date_ - last_tle.Epoch()) > max_terminal_propagation_)
                end_date_ = last_tle.Epoch().Add(max_terminal_propagation_);
        }
    }

    std::string Generate(Groundtrack::Format format)
    {
        size_t num_tles = tles_.size();

        if (num_tles == 0) return "";

        DateTime currtime(start_date_);
        DateTime tle_transition(currtime.Add(max_terminal_propagation_));
        if (num_tles > 1) tle_transition = TLETransitionTime(active_tle_,
                                                             active_tle_+1);

        SGP4 sgp4(tles_[active_tle_]);
        while (currtime < end_date_)
        {
            Eci eci = sgp4.FindPosition(currtime);
            CoordGeodetic geo = eci.ToGeodetic();
            latlons_.push_back(std::make_tuple(currtime, geo));

            if (currtime >= tle_transition && active_tle_ < num_tles - 1)
            {
                active_tle_++;
                sgp4.SetTle(tles_[active_tle_]);
                tle_transition = TLETransitionTime(active_tle_, active_tle_+1);
            }
            currtime = currtime.Add(dt_);
        }

        std::string gt_out;

        switch(format)
        {
        case(Groundtrack::Format::GeoJSON):
            gt_out = GenGeoJSON();
        break;
        }
        return gt_out;
    }

private:
    DateTime                                start_date_;
    DateTime                                end_date_;
    TimeSpan                                dt_;
    std::vector<Tle>                             tles_;
    std::vector<std::tuple<DateTime, CoordGeodetic> > latlons_;
    size_t                                  active_tle_; // index into tles_.
    const TimeSpan                          max_terminal_propagation_; // 7 days

    /**
     * Calculate the midpoint in time between TLEs with the
     * given indices into the tle_ vector.
     */
    DateTime TLETransitionTime(const size_t tle1, const size_t tle2) const
    {
        DateTime t;

        if (tle1 < tles_.size() - 1 && tle2 < tles_.size()) {
            t = tles_[tle1].Epoch() +
                            (tles_[tle2].Epoch() -
                             tles_[tle1].Epoch()).Multiply(0.5);
        }
        else
            t = tles_.back().Epoch().Add(max_terminal_propagation_);

        return t;
    }

    std::string GenGeoJSON()
    {
        std::string geojson_preamble = "{\"type\":\"FeatureCollection\","
                         "\"features\":["
                         "{"
                         "\"type\": \"Feature\","
                         "\"properties\":"
                         "{"
                         "\"name\":\"[...]\""
                         "},"
                         "\"geometry\":"
                         "{"
                         "\"type\":\"LineString\","
                         "\"coordinates\": [";
        std::string geojson_terminator = "]}}]}";
        std::string coords = "";

        size_t numpoints = latlons_.size();
        for (size_t i = 0; i < numpoints; ++i)
        {
            std::string comma = ",";
            if (i == numpoints - 1)
                comma = "";
            std::string coord = "[" + std::get<1>(latlons_[i]).ToStringLonLat() +
                            "]" + comma;
            coords.append(coord);
        }
        std::string geojson = geojson_preamble + coords + geojson_terminator;
        return geojson;
    }

};

int main(int argc, char **argv)
{
    struct tm start_tm, end_tm;
    DateTime start_time, end_time;
    std::string tle_filename;
    int dt = 60; // delta time between groundtrack points
	int c;
    char *s_opt = 0, *e_opt = 0, *t_opt = 0, *f_opt = 0;
    char *zero_opt = 0, *one_opt = 0, *two_opt = 0;

    std::string options("0:1:2:3:s:e:t:f:");
    while ( (c = getopt(argc, argv, options.c_str())) != -1) {
        switch (c) {
        case '0':
        	zero_opt = optarg;
        	break;
        case '1':
        	one_opt = optarg;
        	break;
        case '2':
        	two_opt = optarg;
            break;
        case 's':
            s_opt = optarg;
            if (strptime(s_opt, "%Y-%m-%d %H:%M:%S", &start_tm) == NULL) {
                std::cerr << "Error parsing start time: " << s_opt << "\n";
                exit(0);
            }
            start_time.Initialise(1900 + start_tm.tm_year,
                                  start_tm.tm_mon + 1,
                                  start_tm.tm_mday,
                                  start_tm.tm_hour,
                                  start_tm.tm_min,
                                  start_tm.tm_sec,
                                  0);
            break;
        case 'e':
            e_opt = optarg;
            if (strptime(e_opt, "%Y-%m-%d %H:%M:%S", &end_tm) == NULL) {
                std::cerr << "Error parsing end time: " << e_opt << "\n";
                exit(0);
            }
            end_time.Initialise(1900 + end_tm.tm_year,
                                end_tm.tm_mon + 1,
                                end_tm.tm_mday,
                                end_tm.tm_hour,
                                end_tm.tm_min,
                                end_tm.tm_sec,
                                0);
            break;
        case 't':
            t_opt = optarg;
            dt = atoi(t_opt);
            break;
        case 'f':
            f_opt = optarg;
            tle_filename = f_opt;
            break;
        case '?':
            break;
        default:
            printf ("?? getopt returned character code 0%o ??\n", c);
        }
    }

    // Parse non-option arguments.
    if (optind < argc) {
        while (optind < argc)
            printf ("%s ", argv[optind++]);
        printf ("\n");
    }

    // Read TLEs from the input file or piped into stdin.
    std::istream* tle_source;
    std::ifstream tle_file;
    tle_source = &std::cin;
    if (!tle_filename.empty()) {
        tle_file.open(tle_filename.c_str());
        tle_source = &tle_file;
    }
    std::string line1, line2;
    std::vector<Tle> tles;

    while(!safeGetline(*tle_source, line1).eof()) {
        safeGetline(*tle_source, line2);
        if (line1.empty() || line2.empty())
            continue;
        // line1 = rtrim(line1);
        // line2 = rtrim(line2);
        try {
            Tle tle(line1, line2);
            if (tle.Epoch() >= start_time.AddDays(-1.0 * Groundtrack::max_prop_days) &&
                tle.Epoch() <= end_time.AddDays(Groundtrack::max_prop_days))
            {
                tles.push_back(tle);
            }
        } catch(TleException& e) {
            std::cerr << "TleException: " << e.what() << "\n";
            continue;
        }
    }
    Groundtrack gt(start_time, end_time, dt, std::move(tles));
    std::cout << gt.Generate(Groundtrack::Format::GeoJSON) << std::endl;

    exit (0);
	return 0;
}<commit_msg>Add verbose flag.<commit_after>/*
* Copyright 2014 Adam Hollidge <adam@anh.io>
*/

#include <SGP4.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <tuple>
#include <algorithm>
#include <utility>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

static inline std::istream& safeGetline(std::istream& is, std::string& t)
{
    t.clear();

    // The characters in the stream are read one-by-one using a std::streambuf.
    // That is faster than reading them one-by-one using the std::istream.
    // Code that uses streambuf this way must be guarded by a sentry object.
    // The sentry object performs various tasks,
    // such as thread synchronization and updating the stream state.

    std::istream::sentry se(is, true);
    std::streambuf* sb = is.rdbuf();

    for(;;) {
        int c = sb->sbumpc();
        switch (c) {
        case '\n':
            return is;
        case '\r':
            if(sb->sgetc() == '\n')
                sb->sbumpc();
            return is;
        case EOF:
            // Also handle the case when the last line has no line ending
            if(t.empty())
                is.setstate(std::ios::eofbit);
            return is;
        default:
            t += (char)c;
        }
    }
}

// Chronological TLE sort.
bool chron(const Tle& a, const Tle& b)
{
    return a.Epoch() < b.Epoch();
}

class Groundtrack
{
public:
    enum Format {
        GeoJSON
    };
    static const int max_prop_days = 7;

    Groundtrack(DateTime start_date,
                DateTime end_date,
                int dt,
                std::vector<Tle> tles)
                : start_date_(start_date),
                  end_date_(end_date),
                  dt_(TimeSpan(0, 0, dt)),
                  tles_(tles),
                  active_tle_(0),
                  max_terminal_propagation_(max_prop_days, 0, 0, 0, 0)
    {
        std::sort(tles_.begin(), tles_.end(), chron);

        // Roll back end date if it goes too far beyond
        // the last TLE.
        if (!tles_.empty()) {
            Tle last_tle = tles_.back();
            if ((end_date_ - last_tle.Epoch()) > max_terminal_propagation_)
                end_date_ = last_tle.Epoch().Add(max_terminal_propagation_);
        }
    }

    std::string Generate(Groundtrack::Format format)
    {
        size_t num_tles = tles_.size();

        if (num_tles == 0) return "";

        DateTime currtime(start_date_);
        DateTime tle_transition(currtime.Add(max_terminal_propagation_));
        if (num_tles > 1) tle_transition = TLETransitionTime(active_tle_,
                                                             active_tle_+1);

        SGP4 sgp4(tles_[active_tle_]);
        while (currtime < end_date_)
        {
            Eci eci = sgp4.FindPosition(currtime);
            CoordGeodetic geo = eci.ToGeodetic();
            latlons_.push_back(std::make_tuple(currtime, geo));

            if (currtime >= tle_transition && active_tle_ < num_tles - 1)
            {
                active_tle_++;
                sgp4.SetTle(tles_[active_tle_]);
                tle_transition = TLETransitionTime(active_tle_, active_tle_+1);
            }
            currtime = currtime.Add(dt_);
        }

        std::string gt_out;

        switch(format)
        {
        case(Groundtrack::Format::GeoJSON):
            gt_out = GenGeoJSON();
        break;
        }
        return gt_out;
    }

private:
    DateTime                                start_date_;
    DateTime                                end_date_;
    TimeSpan                                dt_;
    std::vector<Tle>                             tles_;
    std::vector<std::tuple<DateTime, CoordGeodetic> > latlons_;
    size_t                                  active_tle_; // index into tles_.
    const TimeSpan                          max_terminal_propagation_; // 7 days

    /**
     * Calculate the midpoint in time between TLEs with the
     * given indices into the tle_ vector.
     */
    DateTime TLETransitionTime(const size_t tle1, const size_t tle2) const
    {
        DateTime t;

        if (tle1 < tles_.size() - 1 && tle2 < tles_.size()) {
            t = tles_[tle1].Epoch() +
                            (tles_[tle2].Epoch() -
                             tles_[tle1].Epoch()).Multiply(0.5);
        }
        else
            t = tles_.back().Epoch().Add(max_terminal_propagation_);

        return t;
    }

    std::string GenGeoJSON()
    {
        std::string geojson_preamble = "{\"type\":\"FeatureCollection\","
                         "\"features\":["
                         "{"
                         "\"type\": \"Feature\","
                         "\"properties\":"
                         "{"
                         "\"name\":\"[...]\""
                         "},"
                         "\"geometry\":"
                         "{"
                         "\"type\":\"LineString\","
                         "\"coordinates\": [";
        std::string geojson_terminator = "]}}]}";
        std::string coords = "";

        size_t numpoints = latlons_.size();
        for (size_t i = 0; i < numpoints; ++i)
        {
            std::string comma = ",";
            if (i == numpoints - 1)
                comma = "";
            std::string coord = "[" + std::get<1>(latlons_[i]).ToStringLonLat() +
                            "]" + comma;
            coords.append(coord);
        }
        std::string geojson = geojson_preamble + coords + geojson_terminator;
        return geojson;
    }

};

int main(int argc, char **argv)
{
    struct tm start_tm, end_tm;
    DateTime start_time, end_time;
    std::string tle_filename;
    int dt = 60; // delta time between groundtrack points
	int c;
    char *s_opt = 0, *e_opt = 0, *t_opt = 0, *f_opt = 0;
    char *zero_opt = 0, *one_opt = 0, *two_opt = 0;
    bool verbose = false;

    std::string options("0:1:2:3:s:e:t:f:v");
    while ( (c = getopt(argc, argv, options.c_str())) != -1) {
        switch (c) {
        case '0':
        	zero_opt = optarg;
        	break;
        case '1':
        	one_opt = optarg;
        	break;
        case '2':
        	two_opt = optarg;
            break;
        case 's':
            s_opt = optarg;
            if (strptime(s_opt, "%Y-%m-%d %H:%M:%S", &start_tm) == NULL) {
                std::cerr << "Error parsing start time: " << s_opt << "\n";
                exit(0);
            }
            start_time.Initialise(1900 + start_tm.tm_year,
                                  start_tm.tm_mon + 1,
                                  start_tm.tm_mday,
                                  start_tm.tm_hour,
                                  start_tm.tm_min,
                                  start_tm.tm_sec,
                                  0);
            break;
        case 'e':
            e_opt = optarg;
            if (strptime(e_opt, "%Y-%m-%d %H:%M:%S", &end_tm) == NULL) {
                std::cerr << "Error parsing end time: " << e_opt << "\n";
                exit(0);
            }
            end_time.Initialise(1900 + end_tm.tm_year,
                                end_tm.tm_mon + 1,
                                end_tm.tm_mday,
                                end_tm.tm_hour,
                                end_tm.tm_min,
                                end_tm.tm_sec,
                                0);
            break;
        case 't':
            t_opt = optarg;
            dt = atoi(t_opt);
            break;
        case 'f':
            f_opt = optarg;
            tle_filename = f_opt;
            break;
        case 'v':
            verbose = true;
        case '?':
            break;
        default:
            printf ("?? getopt returned character code 0%o ??\n", c);
        }
    }

    // Parse non-option arguments.
    if (optind < argc) {
        while (optind < argc)
            printf ("%s ", argv[optind++]);
        printf ("\n");
    }

    // Read TLEs from the input file or piped into stdin.
    std::istream* tle_source;
    std::ifstream tle_file;
    tle_source = &std::cin;
    if (!tle_filename.empty()) {
        tle_file.open(tle_filename.c_str());
        tle_source = &tle_file;
    }
    std::string line1, line2;
    std::vector<Tle> tles;

    if (verbose) std::cerr << "Reading TLEs.\n";
    while(!safeGetline(*tle_source, line1).eof())
    {
        safeGetline(*tle_source, line2);
        if (line1.empty() || line2.empty())
            continue;
        // line1 = rtrim(line1);
        // line2 = rtrim(line2);
        try {
            Tle tle(line1, line2);
            if (tle.Epoch() >= start_time.AddDays(-1.0 * Groundtrack::max_prop_days) &&
                tle.Epoch() <= end_time.AddDays(Groundtrack::max_prop_days))
            {
                tles.push_back(tle);
            }
        } catch(TleException& e)
        {
            if (verbose) std::cerr << "TleException: " << e.what() << "\n";
            continue;
        }
    }
    if (verbose) std::cerr << "Done reading TLEs.\nGenerating groundtrack.\n";

    Groundtrack gt(start_time, end_time, dt, std::move(tles));
    std::cout << gt.Generate(Groundtrack::Format::GeoJSON) << std::endl;

    if (verbose) std::cerr << "Done generating groundtrack. Exiting.\n";

    exit (0);
	return 0;
}<|endoftext|>