<commit_before>/*
 * Copyright 2004-2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "astutil.h"
#include "expr.h"
#include "optimizations.h"
#include "passes.h"
#include "resolveIntents.h"
#include "stmt.h"
#include "stringutil.h"
#include "symbol.h"
#include "type.h"

static Type* getWrapRecordBaseType(Type* type);

//
// removes _array and _domain wrapper records
//
void
removeWrapRecords() {
  //
  // do not remove wrap records if dead code elimination is disabled
  // (or weakened because inlining or copy propagation is disabled)
  // because code associated with accesses to the removed
  // _valueType field will remain
  //
  if (fNoDeadCodeElimination || fNoInline || fNoCopyPropagation)
    return;

  //
  // replace use of _valueType field with type
  //
  forv_Vec(CallExpr, call, gCallExprs) {
    if (call->isPrimitive(PRIM_GET_PRIV_CLASS)) {
      SET_LINENO(call);
      call->get(1)->replace(new SymExpr(call->get(1)->typeInfo()->symbol));
    }
  }

  //
  // remove defs of _valueType field
  //
  forv_Vec(CallExpr, call, gCallExprs) {
    if (call->isPrimitive(PRIM_SET_MEMBER) ||
        call->isPrimitive(PRIM_GET_MEMBER) ||
        call->isPrimitive(PRIM_GET_MEMBER_VALUE)) {
      if (SymExpr* se = toSymExpr(call->get(2))) {
        if (!strcmp(se->var->name, "_valueType")) {
          se->getStmtExpr()->remove();
        }
      }
    }
  }

  //
  // remove _valueType fields
  //
  forv_Vec(AggregateType, ct, gAggregateTypes) {
    for_fields(field, ct) {
      if (!strcmp(field->name, "_valueType"))
        field->defPoint->remove();
    }
  }

  //
  // remove formals for _valueType fields in constructors
  //
  compute_call_sites();
  forv_Vec(FnSymbol, fn, gFnSymbols) {
    for_formals(formal, fn) {
      if (!strcmp(formal->name, "_valueType")) {
        forv_Vec(CallExpr, call, *fn->calledBy) {
          formal_to_actual(call, formal)->remove();
        }
        formal->defPoint->remove();
      }
    }
  }

  //
  // replace accesses of _value with wrap record
  //
  forv_Vec(CallExpr, call, gCallExprs) {
    if (call->isPrimitive(PRIM_SET_MEMBER)) {
      if (SymExpr* se = toSymExpr(call->get(1))) {
        if (isRecordWrappedType(se->var->type)) {
          call->primitive = primitives[PRIM_MOVE];
          call->get(2)->remove();
        }
      }
    } else if (call->isPrimitive(PRIM_GET_MEMBER)) {
      if (SymExpr* se = toSymExpr(call->get(1))) {
        if (isRecordWrappedType(se->var->type)) {
          call->primitive = primitives[PRIM_ADDR_OF];
          call->get(2)->remove();
        }
      }
    } else if (call->isPrimitive(PRIM_GET_MEMBER_VALUE)) {
      if (SymExpr* se = toSymExpr(call->get(1))) {
        if (isRecordWrappedType(se->var->type)) {
          call->replace(se->remove());
        }
        if (se->var->type->symbol->hasFlag(FLAG_REF)) {
          Type* vt = se->getValType();
          if (isRecordWrappedType(vt)) {
            SET_LINENO(call);
            call->replace(new CallExpr(PRIM_DEREF, se->remove()));
          }
        }
      }
    }
  }

  //
  // scalar replace wrap records
  //
  forv_Vec(VarSymbol, var, gVarSymbols) {
    if (Type* type = getWrapRecordBaseType(var->type))
      if (!var->defPoint->parentSymbol->hasFlag(FLAG_REF))
        var->type = type;
  }
  forv_Vec(ArgSymbol, arg, gArgSymbols) {
    if (Type* type = getWrapRecordBaseType(arg->type)) {
      arg->intent = blankIntentForType(type); // see test/arrays/deitz/part7/test_out_array
      arg->type = type;
    }
  }
  forv_Vec(FnSymbol, fn, gFnSymbols) {
    if (Type* type = getWrapRecordBaseType(fn->retType))
      fn->retType = type;
  }

  //
  // fix array element type for arrays of arrays and arrays of domains
  //
  forv_Vec(AggregateType, ct, gAggregateTypes) {
    if (ct->symbol->hasFlag(FLAG_DATA_CLASS)) {
      if (TypeSymbol* ts = getDataClassType(ct->symbol)) {
        if (isRecordWrappedType(ts->typeInfo())) {
          setDataClassType(ct->symbol, ts->type->getField("_value")->type->symbol);
        }
      }
    }
  }
}

static Type*
getWrapRecordBaseType(Type* type) {
  if (isRecordWrappedType(type)) {
    return type->getField("_value")->type;
  } else if (type->symbol->hasFlag(FLAG_REF)) {
    Type* vt = type->getValType();
    if (isRecordWrappedType(vt)) {
      return vt->getField("_value")->type->refType;
    }
  }
  return NULL;
}

<commit_msg>Revise removeWrapRecords to avoid generating bogus C code.<commit_after>/*
 * Copyright 2004-2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "astutil.h"
#include "expr.h"
#include "optimizations.h"
#include "passes.h"
#include "resolveIntents.h"
#include "stmt.h"
#include "stringutil.h"
#include "symbol.h"
#include "type.h"
#include "stlUtil.h"

static Type* getWrapRecordBaseType(Type* type);

//
// removes _array and _domain wrapper records
//
void
removeWrapRecords() {
  //
  // do not remove wrap records if dead code elimination is disabled
  // (or weakened because inlining or copy propagation is disabled)
  // because code associated with accesses to the removed
  // _valueType field will remain
  //
  if (fNoDeadCodeElimination || fNoInline || fNoCopyPropagation)
    return;

  //
  // replace use of _valueType field with type
  //
  forv_Vec(CallExpr, call, gCallExprs) {
    if (call->isPrimitive(PRIM_GET_PRIV_CLASS)) {
      SET_LINENO(call);
      call->get(1)->replace(new SymExpr(call->get(1)->typeInfo()->symbol));
    }
  }

  //
  // remove defs of _valueType field
  //
  forv_Vec(CallExpr, call, gCallExprs) {
    if (call->isPrimitive(PRIM_SET_MEMBER) ||
        call->isPrimitive(PRIM_GET_MEMBER) ||
        call->isPrimitive(PRIM_GET_MEMBER_VALUE)) {
      if (SymExpr* se = toSymExpr(call->get(2))) {
        if (!strcmp(se->var->name, "_valueType")) {
          se->getStmtExpr()->remove();
        }
      }
    }
  }

  //
  // remove _valueType fields
  //
  forv_Vec(AggregateType, ct, gAggregateTypes) {
    for_fields(field, ct) {
      if (!strcmp(field->name, "_valueType"))
        field->defPoint->remove();
    }
  }

  //
  // remove actuals bound to _valueType formals.
  //
  compute_call_sites();
  forv_Vec(FnSymbol, fn, gFnSymbols) {
    for_formals(formal, fn) {
      if (!strcmp(formal->name, "_valueType")) {
        forv_Vec(CallExpr, call, *fn->calledBy) {
          formal_to_actual(call, formal)->remove();
        }
      }
    }
  }

  //
  // remove all uses of _valueType formals, and then the formal itself.
  //
  forv_Vec(FnSymbol, fn, gFnSymbols) {
    for_formals(formal, fn) {
      if (!strcmp(formal->name, "_valueType")) {
        // Remove all uses of _valueType within the body of this function.
        std::vector<SymExpr*> symExprs;
        collectSymExprsSTL(fn->body, symExprs);
        for_vector(SymExpr, se, symExprs) {
          // Ignore dead ones.
          if (se->parentSymbol == NULL)
            continue;
          // Weed out all but the formal we're interested in.
          if (se->var != formal)
            continue;
          // OK, remove the entire statement accessing the _valueType formal.
          Expr* stmt = se->getStmtExpr();
          stmt->remove();
        }
        formal->defPoint->remove();
      }
    }
  }

  //
  // replace accesses of _value with wrap record
  //
  forv_Vec(CallExpr, call, gCallExprs) {
    if (call->parentSymbol == NULL)
      continue;

    if (call->isPrimitive(PRIM_SET_MEMBER)) {
      if (SymExpr* se = toSymExpr(call->get(1))) {
        if (isRecordWrappedType(se->var->type)) {
          call->primitive = primitives[PRIM_MOVE];
          call->get(2)->remove();
        }
      }
    } else if (call->isPrimitive(PRIM_GET_MEMBER)) {
      if (SymExpr* se = toSymExpr(call->get(1))) {
        if (isRecordWrappedType(se->var->type)) {
          call->primitive = primitives[PRIM_ADDR_OF];
          call->get(2)->remove();
        }
      }
    } else if (call->isPrimitive(PRIM_GET_MEMBER_VALUE)) {
      if (SymExpr* se = toSymExpr(call->get(1))) {
        if (isRecordWrappedType(se->var->type)) {
          call->replace(se->remove());
        }
        if (se->var->type->symbol->hasFlag(FLAG_REF)) {
          Type* vt = se->getValType();
          if (isRecordWrappedType(vt)) {
            SET_LINENO(call);
            call->replace(new CallExpr(PRIM_DEREF, se->remove()));
          }
        }
      }
    }
  }

  //
  // scalar replace wrap records
  //
  forv_Vec(VarSymbol, var, gVarSymbols) {
    if (Type* type = getWrapRecordBaseType(var->type))
      if (!var->defPoint->parentSymbol->hasFlag(FLAG_REF))
        var->type = type;
  }
  forv_Vec(ArgSymbol, arg, gArgSymbols) {
    if (Type* type = getWrapRecordBaseType(arg->type)) {
      arg->intent = blankIntentForType(type); // see test/arrays/deitz/part7/test_out_array
      arg->type = type;
    }
  }
  forv_Vec(FnSymbol, fn, gFnSymbols) {
    if (Type* type = getWrapRecordBaseType(fn->retType))
      fn->retType = type;
  }

  //
  // fix array element type for arrays of arrays and arrays of domains
  //
  forv_Vec(AggregateType, ct, gAggregateTypes) {
    if (ct->symbol->hasFlag(FLAG_DATA_CLASS)) {
      if (TypeSymbol* ts = getDataClassType(ct->symbol)) {
        if (isRecordWrappedType(ts->typeInfo())) {
          setDataClassType(ct->symbol, ts->type->getField("_value")->type->symbol);
        }
      }
    }
  }
}

static Type*
getWrapRecordBaseType(Type* type) {
  if (isRecordWrappedType(type)) {
    return type->getField("_value")->type;
  } else if (type->symbol->hasFlag(FLAG_REF)) {
    Type* vt = type->getValType();
    if (isRecordWrappedType(vt)) {
      return vt->getField("_value")->type->refType;
    }
  }
  return NULL;
}

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/generic/memory/lib/utils/mss_generic_check.H $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mss_generic_check.H
/// @brief Checker functions for generic API
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP

#ifndef _MSS_GENERIC_CHECK_H_
#define _MSS_GENERIC_CHECK_H_

#include <fapi2.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/c_str.H>

namespace mss
{
namespace check
{

///
/// @brief Checks conditional passes and implements traces & exits if it fails
/// @tparam T fapi2 target type
/// @tparam IT input data type
/// @tparam FFDC error callout code type
/// @param[in] i_target fapi2 target
/// @param[in] i_conditional conditional that we are testing against
/// @param[in] i_byte_index byte index
/// @param[in] i_data debug data
/// @param[in] i_ffdc_codes FFDC code
/// @param[in] i_err_str error string - defaulted to ""
/// @return FAPI2_RC_SUCCESS iff okay
///
template< fapi2::TargetType T, typename IT , typename FFDC >
inline fapi2::ReturnCode invalid_value(const fapi2::Target<T>& i_target,
                                       const bool i_conditional,
                                       const size_t i_byte_index,
                                       const IT i_data,
                                       const FFDC i_ffdc_codes,
                                       const char* i_err_str = "")
{
    FAPI_ASSERT(i_conditional,
                fapi2::MSS_FAILED_DATA_INTEGRITY_CHECK().
                set_VALUE(i_data).
                set_BYTE(i_byte_index).
                set_TARGET(i_target).
                set_FFDC_CODE(i_ffdc_codes),
                "%s %s Byte %d, Data returned: %d.",
                spd::c_str(i_target),
                i_err_str,
                i_byte_index,
                i_data);

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;

} // fail_for_invalid_value

} // check
}// mss

#endif
<commit_msg>Add snapshot of generic/memory for master-p10<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/generic/memory/lib/utils/mss_generic_check.H $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mss_generic_check.H
/// @brief Checker functions for generic API
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP

#ifndef _MSS_GENERIC_CHECK_H_
#define _MSS_GENERIC_CHECK_H_

#include <fapi2.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/c_str.H>

namespace mss
{
namespace check
{

///
/// @brief Checks whether any FIRs have lit up on a target
/// @tparam MC MC type for which to check FIR's
/// @tparam T the fapi2::TargetType which hold the FIR bits
/// @param[in] i_target - the target on which to operate
/// @param[in,out] io_rc - the return code for the function
/// @param[out] o_fir_error - true iff a FIR was hit
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template< mss::mc_type MC, fapi2::TargetType T >
fapi2::ReturnCode bad_fir_bits( const fapi2::Target<T>& i_target, fapi2::ReturnCode& io_rc, bool& o_fir_error );

///
/// @brief Checks whether the passed in FIRs have any un-masked errors set
/// @tparam MC MC type for which to check FIR's
/// @tparam T the fapi2::TargetType which hold the FIR bits
/// @param[in] i_target - the target on which to operate
/// @param[in] i_fir_regs - FIR register and mask register
/// @param[out] o_fir_error - true iff a FIR was hit
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template< mss::mc_type MC, fapi2::TargetType T >
inline fapi2::ReturnCode fir_with_mask( const fapi2::Target<T>& i_target,
                                        const std::pair<uint64_t, uint64_t>& i_fir_regs,
                                        bool& o_fir_error )
{
    // Temporary variables to make the code a bit more readable
    const auto FIR_REG = i_fir_regs.first;
    const auto FIR_MASK = i_fir_regs.second;

    fapi2::buffer<uint64_t> l_fir;
    fapi2::buffer<uint64_t> l_fir_mask;

    // Read the registers
    FAPI_TRY(mss::getScom(i_target, FIR_REG, l_fir));
    FAPI_TRY(mss::getScom(i_target, FIR_MASK, l_fir_mask));

    // The mask register will need to be inverted as a 0 in the mask register means the FIR is legit
    // A bitwise and works the opposite way
    l_fir_mask.invert();

    // If we have any unmasked bit, set that we have a FIR error and exit out with success
    // Note: we want to set success here as PRD will find the FIR as "new" and retrigger the procedure this way
    o_fir_error = ((l_fir & l_fir_mask) != 0);

    // And print the information for debuggability
    FAPI_INF("%s %s on reg 0x%016lx value 0x%016lx and mask 0x%016lx value 0x%016lx", mss::c_str(i_target),
             o_fir_error ? "has FIR's set" : "has no FIR's set", FIR_REG, l_fir, FIR_MASK, l_fir_mask.invert());

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Checks whether a FIR or unlocked PLL could be the root cause of another failure
/// @tparam MC MC type for which to check FIR's
/// @tparam T the fapi2::TargetType which hold the FIR bits
/// @param[in] i_target - the target on which to operate
/// @param[in,out] io_rc - the return code for the function
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
/// @note This is a helper function to enable unit testing
///
template< mss::mc_type MC, fapi2::TargetType T >
fapi2::ReturnCode hostboot_fir_or_pll_fail( const fapi2::Target<T>& i_target, fapi2::ReturnCode& io_rc)
{
    // We didn't have an error, so return success
    if(io_rc == fapi2::FAPI2_RC_SUCCESS)
    {
        FAPI_INF("%s has a good return code, returning success", mss::c_str(i_target));
        return fapi2::FAPI2_RC_SUCCESS;
    }

    fapi2::ReturnCode l_fircheck_scom_err(fapi2::FAPI2_RC_SUCCESS);
    bool l_fir_error = false;

    FAPI_ERR("%s has a bad return code, time to check some firs!", mss::c_str(i_target));

    l_fircheck_scom_err = bad_fir_bits<MC>(i_target, io_rc, l_fir_error);

    FAPI_ERR("%s took a fail. FIR was %s", mss::c_str(i_target),
             l_fir_error ? "set - returning FIR RC" : "unset - returning inputted RC");

    // If we had a FIR error, log the original error and return success
    // PRD will handle the original error
    if(l_fir_error)
    {
        fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
    }
    else
    {
        fapi2::current_err = io_rc;
    }

    return fapi2::current_err;
}

///
/// @brief Checks whether a FIR or unlocked PLL could be the root cause of another failure, if a check fir boolean is passed in
/// @tparam MC MC type for which to check FIR's
/// @tparam T the fapi2::TargetType which hold the FIR bits
/// @param[in] i_target - the target on which to operate
/// @param[in,out] io_rc - the return code for the function
/// @param[in] i_check_fir - true IFF the FIR needs to be checked - defaults to true
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template< mss::mc_type MC, fapi2::TargetType T >
fapi2::ReturnCode fir_or_pll_fail( const fapi2::Target<T>& i_target,
                                   fapi2::ReturnCode& io_rc,
                                   const bool i_check_fir = true)
{
#ifdef __HOSTBOOT_MODULE

    fapi2::ReturnCode l_rc(io_rc);

    // If need be, check the FIR below
    if(i_check_fir)
    {
        // Handle any issues according to PRD FIR scheme, as a FIR could have caused this issue
        l_rc = hostboot_fir_or_pll_fail<MC>(i_target, l_rc);
    }

    return l_rc;

#else
    return io_rc;
#endif
}

///
/// @brief Checks conditional passes and implements traces & exits if it fails
/// @tparam T fapi2 target type
/// @tparam IT input data type
/// @tparam FFDC error callout code type
/// @param[in] i_target fapi2 target
/// @param[in] i_conditional conditional that we are testing against
/// @param[in] i_byte_index byte index
/// @param[in] i_data debug data
/// @param[in] i_ffdc_codes FFDC code
/// @param[in] i_err_str error string - defaulted to ""
/// @return FAPI2_RC_SUCCESS iff okay
///
template< fapi2::TargetType T, typename IT , typename FFDC >
inline fapi2::ReturnCode invalid_value(const fapi2::Target<T>& i_target,
                                       const bool i_conditional,
                                       const size_t i_byte_index,
                                       const IT i_data,
                                       const FFDC i_ffdc_codes,
                                       const char* i_err_str = "")
{
    FAPI_ASSERT(i_conditional,
                fapi2::MSS_FAILED_DATA_INTEGRITY_CHECK().
                set_VALUE(i_data).
                set_BYTE(i_byte_index).
                set_TARGET(i_target).
                set_FFDC_CODE(i_ffdc_codes),
                "%s %s Byte %d, Data returned: %d.",
                spd::c_str(i_target),
                i_err_str,
                i_byte_index,
                i_data);

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;

} // fail_for_invalid_value

} // check
}// mss

#endif
<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Harshit Jain <hjain.itbhu@gmail.com>
//

#include "KmlTimeStampTagHandler.h"

#include "MarbleDebug.h"

#include "KmlElementDictionary.h"
#include "GeoDataTimeStamp.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"

namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( TimeStamp )

GeoNode* KmlTimeStampTagHandler::parse( GeoParser& parser ) const
{
    Q_ASSERT( parser.isStartElement() && parser.isValidElement( kmlTag_TimeStamp ) );

    GeoStackItem parentItem = parser.parentElement();

    if ( parentItem.nodeAs<GeoDataFeature>() ) {
        GeoDataTimeStamp timeStamp;
        QString id = parser.attribute( "id" ).trimmed();
        parentItem.nodeAs<GeoDataFeature>()->setTimeStamp( timeStamp );

        return &parentItem.nodeAs<GeoDataFeature>()->timeStamp();
    }
    return 0;
}

}
}
<commit_msg>Must not implicitly cast static_cast result to boolean<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Harshit Jain <hjain.itbhu@gmail.com>
//

#include "KmlTimeStampTagHandler.h"

#include "MarbleDebug.h"

#include "KmlElementDictionary.h"
#include "GeoDataTimeStamp.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"

namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( TimeStamp )

GeoNode* KmlTimeStampTagHandler::parse( GeoParser& parser ) const
{
    Q_ASSERT( parser.isStartElement() && parser.isValidElement( kmlTag_TimeStamp ) );
    GeoStackItem parentItem = parser.parentElement();
    if ( parentItem.is<GeoDataFeature>() ) {
        parentItem.nodeAs<GeoDataFeature>()->setTimeStamp( GeoDataTimeStamp() );
        return &parentItem.nodeAs<GeoDataFeature>()->timeStamp();
    }
    return 0;
}

}
}
<|endoftext|>


<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real
    Copyright (C) 2017 Roman Lebedev

    This library 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 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
*/

#include "decompressors/SamsungV2Decompressor.h"
#include "common/Common.h"                // for uint32, ushort16, int32
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h"              // for BitPumpMSB32
#include "io/ByteStream.h"                // for ByteStream
#include <algorithm>                      // for max
#include <cassert>                        // for assert
#include <type_traits>                    // for underlying_type, underlyin...

namespace rawspeed {

// Seriously Samsung just use lossless jpeg already, it compresses better too :)

// Thanks to Michael Reichmann (Luminous Landscape) for putting Pedro Côrte-Real
// in contact and Loring von Palleske (Samsung) for pointing to the open-source
// code of Samsung's DNG converter at http://opensource.samsung.com/

enum struct SamsungV2Decompressor::OptFlags : uint32 {
  NONE = 0U,       // no flags
  SKIP = 1U << 0U, // Skip checking if we need differences from previous line
  MV = 1U << 1U,   // Simplify motion vector definition
  QP = 1U << 2U,   // Don't scale the diff values

  // all possible flags
  ALL = SKIP | MV | QP,
};

constexpr SamsungV2Decompressor::OptFlags
operator|(SamsungV2Decompressor::OptFlags lhs,
          SamsungV2Decompressor::OptFlags rhs) {
  return static_cast<SamsungV2Decompressor::OptFlags>(
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          lhs) |
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          rhs));
}

constexpr bool operator&(SamsungV2Decompressor::OptFlags lhs,
                         SamsungV2Decompressor::OptFlags rhs) {
  return SamsungV2Decompressor::OptFlags::NONE !=
         static_cast<SamsungV2Decompressor::OptFlags>(
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 lhs) &
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 rhs));
}

SamsungV2Decompressor::SamsungV2Decompressor(const RawImage& image,
                                             const ByteStream& bs, int bit)
    : AbstractSamsungDecompressor(image), bits(bit) {
  BitPumpMSB32 startpump(bs);

  // Process the initial metadata bits, we only really use initVal, width and
  // height (the last two match the TIFF values anyway)
  startpump.getBits(16); // NLCVersion
  startpump.getBits(4);  // ImgFormat
  bitDepth = startpump.getBits(4) + 1;
  startpump.getBits(4); // NumBlkInRCUnit
  startpump.getBits(4); // CompressionRatio
  width = startpump.getBits(16);
  height = startpump.getBits(16);
  startpump.getBits(16); // TileWidth
  startpump.getBits(4);  // reserved

  // The format includes an optimization code that sets 3 flags to change the
  // decoding parameters
  const uint32 optflags = startpump.getBits(4);
  if (optflags > static_cast<uint32>(OptFlags::ALL))
    ThrowRDE("Invalid opt flags %x", optflags);
  _flags = static_cast<OptFlags>(optflags);

  startpump.getBits(8); // OverlapWidth
  startpump.getBits(8); // reserved
  startpump.getBits(8); // Inc
  startpump.getBits(2); // reserved
  initVal = startpump.getBits(14);

  if (width == 0 || height == 0 || width % 16 != 0 || width > 6496 ||
      height > 4336)
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);

  if (width != static_cast<uint32>(mRaw->dim.x) ||
      height != static_cast<uint32>(mRaw->dim.y))
    ThrowRDE("EXIF image dimensions do not match dimensions from raw header");

  data = startpump.getStream(startpump.getRemainSize());
}

void SamsungV2Decompressor::decompress() {
  switch (_flags) {
  case OptFlags::NONE:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::NONE>(row);
    break;
  case OptFlags::ALL:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::ALL>(row);
    break;

  case OptFlags::SKIP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP>(row);
    break;
  case OptFlags::MV:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::MV>(row);
    break;
  case OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::QP>(row);
    break;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
  case OptFlags::SKIP | OptFlags::MV:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::MV>(row);
    break;
  case OptFlags::SKIP | OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::QP>(row);
    break;

  case OptFlags::MV | OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::MV | OptFlags::QP>(row);
    break;
#pragma GCC diagnostic pop

  default:
    __builtin_unreachable();
  }
}

template <SamsungV2Decompressor::OptFlags optflags>
void SamsungV2Decompressor::decompressRow(uint32 row) {
  // The format is relatively straightforward. Each line gets encoded as a set
  // of differences from pixels from another line. Pixels are grouped in blocks
  // of 16 (8 green, 8 red or blue). Each block is encoded in three sections.
  // First 1 or 4 bits to specify which reference pixels to use, then a section
  // that specifies for each pixel the number of bits in the difference, then
  // the actual difference bits

  // Align pump to 16byte boundary
  const auto line_offset = data.getPosition();
  if ((line_offset & 0xf) != 0)
    data.skipBytes(16 - (line_offset & 0xf));

  BitPumpMSB32 pump(data);

  auto* img = reinterpret_cast<ushort16*>(mRaw->getData(0, row));
  ushort16* img_up = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(row) - 1)));
  ushort16* img_up2 = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(row) - 2)));

  // Initialize the motion and diff modes at the start of the line
  uint32 motion = 7;
  // By default we are not scaling values at all
  int32 scale = 0;

  uint32 diffBitsMode[3][2] = {{0}};
  for (auto& i : diffBitsMode)
    i[0] = i[1] = (row == 0 || row == 1) ? 7 : 4;

  assert(width >= 16);
  for (uint32 col = 0; col < width; col += 16) {
    if (!(optflags & OptFlags::QP) && !(col & 63)) {
      int32 scalevals[] = {0, -2, 2};
      uint32 i = pump.getBits(2);
      scale = i < 3 ? scale + scalevals[i] : pump.getBits(12);
    }

    // First we figure out which reference pixels mode we're in
    if (optflags & OptFlags::MV)
      motion = pump.getBits(1) ? 3 : 7;
    else if (!pump.getBits(1))
      motion = pump.getBits(3);

    if ((row == 0 || row == 1) && (motion != 7))
      ThrowRDE("At start of image and motion isn't 7. File corrupted?");

    if (motion == 7) {
      // The base case, just set all pixels to the previous ones on the same
      // line If we're at the left edge we just start at the initial value
      for (uint32 i = 0; i < 16; i++)
        img[i] = (col == 0) ? initVal : *(img + i - 2);
    } else {
      // The complex case, we now need to actually lookup one or two lines
      // above
      if (row < 2)
        ThrowRDE(
            "Got a previous line lookup on first two lines. File corrupted?");

      int32 motionOffset[7] = {-4, -2, -2, 0, 0, 2, 4};
      int32 motionDoAverage[7] = {0, 0, 1, 0, 1, 0, 0};

      int32 slideOffset = motionOffset[motion];
      int32 doAverage = motionDoAverage[motion];

      for (uint32 i = 0; i < 16; i++) {
        ushort16* refpixel;

        if ((row + i) & 0x1) {
          // Red or blue pixels use same color two lines up
          refpixel = img_up2 + i + slideOffset;

          if (col == 0 && img_up2 > refpixel)
            ThrowRDE("Bad motion %u at the beginning of the row", motion);
        } else {
          // Green pixel N uses Green pixel N from row above
          // (top left or top right)
          refpixel = img_up + i + slideOffset + (((i % 2) != 0) ? -1 : 1);

          if (col == 0 && img_up > refpixel)
            ThrowRDE("Bad motion %u at the beginning of the row", motion);
        }

        // In some cases we use as reference interpolation of this pixel and
        // the next
        if (doAverage)
          img[i] = (*refpixel + *(refpixel + 2) + 1) >> 1;
        else
          img[i] = *refpixel;
      }
    }

    // Figure out how many difference bits we have to read for each pixel
    uint32 diffBits[4] = {0};
    if (optflags & OptFlags::SKIP || !pump.getBits(1)) {
      uint32 flags[4];
      for (unsigned int& flag : flags)
        flag = pump.getBits(2);

      for (uint32 i = 0; i < 4; i++) {
        // The color is 0-Green 1-Blue 2-Red
        uint32 colornum = (row % 2 != 0) ? i >> 1 : ((i >> 1) + 2) % 3;

        assert(flags[i] <= 3);
        switch (flags[i]) {
        case 0:
          diffBits[i] = diffBitsMode[colornum][0];
          break;
        case 1:
          diffBits[i] = diffBitsMode[colornum][0] + 1;
          break;
        case 2:
          diffBits[i] = diffBitsMode[colornum][0] - 1;
          break;
        case 3:
          diffBits[i] = pump.getBits(4);
          break;
        default:
          __builtin_unreachable();
        }

        diffBitsMode[colornum][0] = diffBitsMode[colornum][1];
        diffBitsMode[colornum][1] = diffBits[i];

        if (diffBits[i] > bitDepth + 1)
          ThrowRDE("Too many difference bits. File corrupted?");
      }
    }

    // Actually read the differences and write them to the pixels
    for (uint32 i = 0; i < 16; i++) {
      uint32 len = diffBits[i >> 2];
      int32 diff = pump.getBits(len);

      // If the first bit is 1 we need to turn this into a negative number
      if (len != 0 && diff >> (len - 1))
        diff -= (1 << len);

      ushort16* value = nullptr;
      // Apply the diff to pixels 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
      if (row % 2)
        value = &img[((i & 0x7) << 1) + 1 - (i >> 3)];
      else
        value = &img[((i & 0x7) << 1) + (i >> 3)];

      diff = diff * (scale * 2 + 1) + scale;
      *value = clampBits(static_cast<int>(*value) + diff, bits);
    }

    img += 16;
    img_up += 16;
    img_up2 += 16;
  }

  data.skipBytes(pump.getBufferPosition());
}

} // namespace rawspeed
<commit_msg>SamsungV2Decompressor::decompressRow(): mark static data as such<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real
    Copyright (C) 2017 Roman Lebedev

    This library 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 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
*/

#include "decompressors/SamsungV2Decompressor.h"
#include "common/Common.h"                // for uint32, ushort16, int32
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h"              // for BitPumpMSB32
#include "io/ByteStream.h"                // for ByteStream
#include <algorithm>                      // for max
#include <cassert>                        // for assert
#include <type_traits>                    // for underlying_type, underlyin...

namespace rawspeed {

// Seriously Samsung just use lossless jpeg already, it compresses better too :)

// Thanks to Michael Reichmann (Luminous Landscape) for putting Pedro Côrte-Real
// in contact and Loring von Palleske (Samsung) for pointing to the open-source
// code of Samsung's DNG converter at http://opensource.samsung.com/

enum struct SamsungV2Decompressor::OptFlags : uint32 {
  NONE = 0U,       // no flags
  SKIP = 1U << 0U, // Skip checking if we need differences from previous line
  MV = 1U << 1U,   // Simplify motion vector definition
  QP = 1U << 2U,   // Don't scale the diff values

  // all possible flags
  ALL = SKIP | MV | QP,
};

constexpr SamsungV2Decompressor::OptFlags
operator|(SamsungV2Decompressor::OptFlags lhs,
          SamsungV2Decompressor::OptFlags rhs) {
  return static_cast<SamsungV2Decompressor::OptFlags>(
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          lhs) |
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          rhs));
}

constexpr bool operator&(SamsungV2Decompressor::OptFlags lhs,
                         SamsungV2Decompressor::OptFlags rhs) {
  return SamsungV2Decompressor::OptFlags::NONE !=
         static_cast<SamsungV2Decompressor::OptFlags>(
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 lhs) &
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 rhs));
}

SamsungV2Decompressor::SamsungV2Decompressor(const RawImage& image,
                                             const ByteStream& bs, int bit)
    : AbstractSamsungDecompressor(image), bits(bit) {
  BitPumpMSB32 startpump(bs);

  // Process the initial metadata bits, we only really use initVal, width and
  // height (the last two match the TIFF values anyway)
  startpump.getBits(16); // NLCVersion
  startpump.getBits(4);  // ImgFormat
  bitDepth = startpump.getBits(4) + 1;
  startpump.getBits(4); // NumBlkInRCUnit
  startpump.getBits(4); // CompressionRatio
  width = startpump.getBits(16);
  height = startpump.getBits(16);
  startpump.getBits(16); // TileWidth
  startpump.getBits(4);  // reserved

  // The format includes an optimization code that sets 3 flags to change the
  // decoding parameters
  const uint32 optflags = startpump.getBits(4);
  if (optflags > static_cast<uint32>(OptFlags::ALL))
    ThrowRDE("Invalid opt flags %x", optflags);
  _flags = static_cast<OptFlags>(optflags);

  startpump.getBits(8); // OverlapWidth
  startpump.getBits(8); // reserved
  startpump.getBits(8); // Inc
  startpump.getBits(2); // reserved
  initVal = startpump.getBits(14);

  if (width == 0 || height == 0 || width % 16 != 0 || width > 6496 ||
      height > 4336)
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);

  if (width != static_cast<uint32>(mRaw->dim.x) ||
      height != static_cast<uint32>(mRaw->dim.y))
    ThrowRDE("EXIF image dimensions do not match dimensions from raw header");

  data = startpump.getStream(startpump.getRemainSize());
}

void SamsungV2Decompressor::decompress() {
  switch (_flags) {
  case OptFlags::NONE:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::NONE>(row);
    break;
  case OptFlags::ALL:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::ALL>(row);
    break;

  case OptFlags::SKIP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP>(row);
    break;
  case OptFlags::MV:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::MV>(row);
    break;
  case OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::QP>(row);
    break;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
  case OptFlags::SKIP | OptFlags::MV:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::MV>(row);
    break;
  case OptFlags::SKIP | OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::QP>(row);
    break;

  case OptFlags::MV | OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::MV | OptFlags::QP>(row);
    break;
#pragma GCC diagnostic pop

  default:
    __builtin_unreachable();
  }
}

template <SamsungV2Decompressor::OptFlags optflags>
void SamsungV2Decompressor::decompressRow(uint32 row) {
  // The format is relatively straightforward. Each line gets encoded as a set
  // of differences from pixels from another line. Pixels are grouped in blocks
  // of 16 (8 green, 8 red or blue). Each block is encoded in three sections.
  // First 1 or 4 bits to specify which reference pixels to use, then a section
  // that specifies for each pixel the number of bits in the difference, then
  // the actual difference bits

  // Align pump to 16byte boundary
  const auto line_offset = data.getPosition();
  if ((line_offset & 0xf) != 0)
    data.skipBytes(16 - (line_offset & 0xf));

  BitPumpMSB32 pump(data);

  auto* img = reinterpret_cast<ushort16*>(mRaw->getData(0, row));
  ushort16* img_up = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(row) - 1)));
  ushort16* img_up2 = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(row) - 2)));

  // Initialize the motion and diff modes at the start of the line
  uint32 motion = 7;
  // By default we are not scaling values at all
  int32 scale = 0;

  uint32 diffBitsMode[3][2] = {{0}};
  for (auto& i : diffBitsMode)
    i[0] = i[1] = (row == 0 || row == 1) ? 7 : 4;

  assert(width >= 16);
  for (uint32 col = 0; col < width; col += 16) {
    if (!(optflags & OptFlags::QP) && !(col & 63)) {
      static constexpr int32 scalevals[] = {0, -2, 2};
      uint32 i = pump.getBits(2);
      scale = i < 3 ? scale + scalevals[i] : pump.getBits(12);
    }

    // First we figure out which reference pixels mode we're in
    if (optflags & OptFlags::MV)
      motion = pump.getBits(1) ? 3 : 7;
    else if (!pump.getBits(1))
      motion = pump.getBits(3);

    if ((row == 0 || row == 1) && (motion != 7))
      ThrowRDE("At start of image and motion isn't 7. File corrupted?");

    if (motion == 7) {
      // The base case, just set all pixels to the previous ones on the same
      // line If we're at the left edge we just start at the initial value
      for (uint32 i = 0; i < 16; i++)
        img[i] = (col == 0) ? initVal : *(img + i - 2);
    } else {
      // The complex case, we now need to actually lookup one or two lines
      // above
      if (row < 2)
        ThrowRDE(
            "Got a previous line lookup on first two lines. File corrupted?");

      static constexpr int32 motionOffset[7] = {-4, -2, -2, 0, 0, 2, 4};
      static constexpr int32 motionDoAverage[7] = {0, 0, 1, 0, 1, 0, 0};

      int32 slideOffset = motionOffset[motion];
      int32 doAverage = motionDoAverage[motion];

      for (uint32 i = 0; i < 16; i++) {
        ushort16* refpixel;

        if ((row + i) & 0x1) {
          // Red or blue pixels use same color two lines up
          refpixel = img_up2 + i + slideOffset;

          if (col == 0 && img_up2 > refpixel)
            ThrowRDE("Bad motion %u at the beginning of the row", motion);
        } else {
          // Green pixel N uses Green pixel N from row above
          // (top left or top right)
          refpixel = img_up + i + slideOffset + (((i % 2) != 0) ? -1 : 1);

          if (col == 0 && img_up > refpixel)
            ThrowRDE("Bad motion %u at the beginning of the row", motion);
        }

        // In some cases we use as reference interpolation of this pixel and
        // the next
        if (doAverage)
          img[i] = (*refpixel + *(refpixel + 2) + 1) >> 1;
        else
          img[i] = *refpixel;
      }
    }

    // Figure out how many difference bits we have to read for each pixel
    uint32 diffBits[4] = {0};
    if (optflags & OptFlags::SKIP || !pump.getBits(1)) {
      uint32 flags[4];
      for (unsigned int& flag : flags)
        flag = pump.getBits(2);

      for (uint32 i = 0; i < 4; i++) {
        // The color is 0-Green 1-Blue 2-Red
        uint32 colornum = (row % 2 != 0) ? i >> 1 : ((i >> 1) + 2) % 3;

        assert(flags[i] <= 3);
        switch (flags[i]) {
        case 0:
          diffBits[i] = diffBitsMode[colornum][0];
          break;
        case 1:
          diffBits[i] = diffBitsMode[colornum][0] + 1;
          break;
        case 2:
          diffBits[i] = diffBitsMode[colornum][0] - 1;
          break;
        case 3:
          diffBits[i] = pump.getBits(4);
          break;
        default:
          __builtin_unreachable();
        }

        diffBitsMode[colornum][0] = diffBitsMode[colornum][1];
        diffBitsMode[colornum][1] = diffBits[i];

        if (diffBits[i] > bitDepth + 1)
          ThrowRDE("Too many difference bits. File corrupted?");
      }
    }

    // Actually read the differences and write them to the pixels
    for (uint32 i = 0; i < 16; i++) {
      uint32 len = diffBits[i >> 2];
      int32 diff = pump.getBits(len);

      // If the first bit is 1 we need to turn this into a negative number
      if (len != 0 && diff >> (len - 1))
        diff -= (1 << len);

      ushort16* value = nullptr;
      // Apply the diff to pixels 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
      if (row % 2)
        value = &img[((i & 0x7) << 1) + 1 - (i >> 3)];
      else
        value = &img[((i & 0x7) << 1) + (i >> 3)];

      diff = diff * (scale * 2 + 1) + scale;
      *value = clampBits(static_cast<int>(*value) + diff, bits);
    }

    img += 16;
    img_up += 16;
    img_up2 += 16;
  }

  data.skipBytes(pump.getBufferPosition());
}

} // namespace rawspeed
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: xihelper.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2003-11-05 13:41:45 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// ============================================================================

#ifndef SC_XIHELPER_HXX
#define SC_XIHELPER_HXX

#ifndef _MyEDITDATA_HXX
#include <svx/editdata.hxx>
#endif

#ifndef SC_XISTREAM_HXX
#include "xistream.hxx"
#endif
#ifndef SC_XIROOT_HXX
#include "xiroot.hxx"
#endif

class ScMatrix;

// Byte/Unicode strings =======================================================

/** This class represents an unformatted or formatted string and provides importing from stream. */
class XclImpString
{
private:
    String                      maString;       /// The text data of the string.
    XclFormatRunVec             maFormats;      /// All formatting runs.

public:
    /** Constructs an unformatted string. */
    explicit                    XclImpString( const String& rString );
    /** Constructs a formatted string by reading completely from stream. */
    explicit                    XclImpString( XclImpStream& rStrm, XclStrFlags nFlags = EXC_STR_DEFAULT );

                                ~XclImpString();

    /** Insert a formatting run to the format buffer. */
    void                        AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIx );
    /** Reads and appends the formatting information (run count and runs) from stream. */
    void                        ReadFormats( XclImpStream& rStrm );
    /** Reads and appends nRunCount formatting runs from stream. */
    void                        ReadFormats( XclImpStream& rStrm, sal_uInt16 nRunCount );

    /** Returns the pure text data of the string. */
    inline const String&        GetText() const { return maString; }
    /** Returns true, if the string contains formatting information. */
    inline bool                 IsRich() const { return !maFormats.empty(); }
    /** Returns the formatting run vector. */
    inline const XclFormatRunVec& GetFormats() const { return maFormats; }
};

// String->EditEngine conversion ==============================================

class ScBaseCell;
class EditTextObject;

/** This class provides methods to convert an XclImpString.
    @The string can be converted to an edit engine text object or directly
    to a Calc edit cell. */
class XclImpStringHelper : ScfNoInstance
{
public:
    /** Returns a new edit engine text object.
        @param nXFIndex  Index to XF for first text portion (for escapement). */
    static EditTextObject*      CreateTextObject(
                                    const XclImpRoot& rRoot,
                                    const XclImpString& rString,
                                    sal_uInt32 nXFIndex = 0 );

    /** Creates a new text cell or edit cell for a Calc document.
        @param nXFIndex  Index to XF for first text portion (for escapement). */
    static ScBaseCell*          CreateCell(
                                    const XclImpRoot& rRoot,
                                    const XclImpString& rString,
                                    sal_uInt32 nXFIndex = 0 );
};

// Header/footer conversion ===================================================

class EditEngine;
class EditTextObject;
class SfxItemSet;
class SvxFieldItem;
struct XclFontData;

/** Converts an Excel header/footer string into three edit engine text objects.
    @descr  Header/footer content is divided into three parts: Left, center and
    right portion. All formatting information is encoded in the Excel string
    using special character seuences. A control sequence starts with the ampersand
    character.

    Supported control sequences:
    &L                      start of left portion
    &C                      start of center portion
    &R                      start of right portion
    &P                      current page number
    &N                      page count
    &D                      current date
    &T                      current time
    &A                      table name
    &F                      file name without path (see also &Z&F)
    &Z                      file path without file name (converted to full file name, see also &Z&F)
    &Z&F                    file path and name
    &U                      underlining on/off
    &E                      double underlining on/off
    &S                      strikeout characters on/off
    &X                      superscript on/off
    &Y                      subscript on/off
    &"fontname,fontstyle"   use font with name 'fontname' and style 'fontstyle'
    &fontheight             set font height in points ('fontheight' is a decimal value)

    Known but unsupported control sequences:
    &G                      picture
 */
class XclImpHFConverter : protected XclImpRoot, ScfNoCopy
{
private:
    typedef ::std::auto_ptr< EditTextObject >   EditTextObjectPtr;
    typedef ::std::auto_ptr< XclFontData >      XclFontDataPtr;

    EditEngine&                 mrEE;           /// The header/footer edit engine.
    EditTextObjectPtr           mppObjs[ 3 ];   /// Edit engine text objects for all portions.
    ESelection                  mpSels[ 3 ];    /// Edit engine selections for all portions.
    String                      maCurrText;     /// Current text to insert into edit engine.
    XclFontDataPtr              mpFontData;     /// Font data of current text.
    sal_uInt16                  mnCurrObj;      /// The current portion.

public:
    explicit                    XclImpHFConverter( const XclImpRoot& rRoot );
                                ~XclImpHFConverter();

    /** Parses the passed string and creates three new edit engine text objects. */
    void                        ParseString( const String& rHFString );

    /** Creates a ScPageHFItem and inserts it into the passed item set. */
    void                        FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId );

private:
    /** Returns the current edit engine text object. */
    inline EditTextObjectPtr&   GetCurrObj() { return mppObjs[ mnCurrObj ]; }
    /** Returns the current selection. */
    inline ESelection&          GetCurrSel() { return mpSels[ mnCurrObj ]; }

    /** Sets the font attributes at the current selection.
        @descr  After that, the start position of the current selection object is
        adjusted to the end of the selection. */
    void                        SetAttribs();
    /** Resets font data to application default font. */
    void                        ResetFontData();

    /** Inserts maCurrText into edit engine and adjusts the current selection object.
        @descr  The text shall not contain a newline character.
        The text will be cleared after insertion. */
    void                        InsertText();
    /** Inserts a line break and adjusts the current selection object. */
    void                        InsertLineBreak();
    /** Inserts the passed text field and adjusts the current selection object. */
    void                        InsertField( const SvxFieldItem& rFieldItem );

    /** Creates the edit engine text object of current portion from edit engine. */
    void                        CreateCurrObject();
    /** Changes current header/footer portion to eNew.
        @descr  Creates text object of current portion and reinitializes edit engine. */
    void                        SetNewPortion( sal_uInt16 nNew );
};

// URL conversion =============================================================

/** This class contains static methods to decode an URL stored in an Excel file.
    @descr  Excel URLs can contain a sheet name, for instance: path\[test.xls]Sheet1
    This sheet name will be extracted automatically. */
class XclImpUrlHelper : ScfNoInstance
{
public:
    /** Decodes an encoded external document URL with optional sheet name.
        @param rUrl  Returns the decoded file name incl. path.
        @param rTabName  Returns the decoded sheet name.
        @param rbSameWb  Returns true, if the URL is a reference to the own workbook.
        @param rEncodedUrl   An encoded URL from Excel. */
    static void                 DecodeUrl(
                                    String& rUrl,
                                    String& rTabName,
                                    bool& rbSameWb,
                                    const XclImpRoot& rRoot,
                                    const String& rEncodedUrl );

    /** Decodes an encoded external document URL without sheet name.
        @param rUrl  Returns the decoded file name incl. path.
        @param rbSameWb  Returns true, if the URL is a reference to the own workbook.
        @param rEncodedUrl   An encoded URL from Excel. */
    static void                 DecodeUrl(
                                    String& rUrl,
                                    bool& rbSameWb,
                                    const XclImpRoot& rRoot,
                                    const String& rEncodedUrl );

    /** Decodes the passed URL to OLE or DDE link components.
        @descr  For DDE links: Decodes to application name and topic.
        For OLE object links: Decodes to class name and document URL.
        @return  true = decoding was successful, returned strings are valid (not empty). */
    static bool                 DecodeLink( String& rApplic, String& rTopic, const String rEncUrl );
};

// Cached Values ==============================================================

class ScTokenArray;

/** This class stores one cached value of a cached value list (used for instance in
    CRN, EXTERNNAME, tArray). */
class XclImpCachedValue : ScfNoCopy
{
protected:
    typedef ::std::auto_ptr< String >               StringPtr;
    typedef ::std::auto_ptr< const ScTokenArray >   ScTokenArrayPtr;

    StringPtr                   mpStr;      /// Cached value is a string.
    double                      mfValue;    /// Cached value is a double.
    ScTokenArrayPtr             mpTokArr;   /// Cached value is a formula or error code or Boolean.
    sal_uInt8                   mnType;     /// The type of the cached value (EXC_CACHEDVAL_*).
    sal_uInt16                  mnCol;      /// Column index of the cached cell.
    sal_uInt16                  mnRow;      /// Row index of the cached cell.

public:
    /** Creates a cached value and reads contents from stream and stores it with its array address. */
                                XclImpCachedValue( XclImpStream& rStrm,
                                    sal_uInt16 nCol,
                                    sal_uInt16 nRow);
    virtual                     ~XclImpCachedValue();

    /** Returns the type of the cached value (EXC_CACHEDVAL_*). */
    inline sal_uInt8            GetType() const     { return mnType; }
    /** Returns the cached string value, if this is a EXC_CACHEDVAL_STRING. */
    inline const String*        GetString() const   { return mpStr.get(); }
    /** Returns the cached double value if this is a EXC_CACHEDVAL_DOUBLE. */
    inline double               GetValue() const    { return mfValue; }
    /** Returns the token array if this is a Boolean value or error value. */
    inline const ScTokenArray*  GetTokArray() const { return mpTokArr.get(); }

    inline sal_uInt16           GetCol() const    { return mnCol; }
    inline sal_uInt16           GetRow() const    { return mnRow; }
};

class XclImpCachedMatrix
{
protected:
    typedef ScfDelList< XclImpCachedValue > XclImpValueList;

    XclImpValueList             maValueList;     /// List of cached cell values.
    sal_uInt16                  mnColumns;       /// Number of cached columns.
    sal_uInt16                  mnRows;          /// Number of cached rows.

public:
    explicit                    XclImpCachedMatrix( sal_uInt16 nCols, sal_uInt16 nRows);
                                ~XclImpCachedMatrix();

    /** Copies the contents of our cached matrix into the ScMatrix. */
    void                        FillMatrix(ScDocument &rDoc, ScMatrix *pMatrix) const ;

    /** Stores the contents of an external referenced cell in the Value list. */
    inline void                 AppendValue( XclImpCachedValue* pCachedValue ) { maValueList.Append( pCachedValue ); }

    inline sal_uInt16           GetColumns() const { return mnColumns; }
    inline sal_uInt16           GetRows() const    { return mnRows; }
};

// ============================================================================

#endif

<commit_msg>INTEGRATION: CWS cac (1.4.42); FILE MERGED 2003/11/14 12:59:28 dr 1.4.42.2: RESYNC: (1.4-1.5); FILE MERGED 2003/11/03 14:35:08 dr 1.4.42.1: #i4070# use ScMatrix class directly<commit_after>/*************************************************************************
 *
 *  $RCSfile: xihelper.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2004-03-08 11:52:05 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// ============================================================================

#ifndef SC_XIHELPER_HXX
#define SC_XIHELPER_HXX

#ifndef _MyEDITDATA_HXX
#include <svx/editdata.hxx>
#endif

#ifndef SC_MATRIX_HXX
#include "scmatrix.hxx"
#endif

#ifndef SC_XISTREAM_HXX
#include "xistream.hxx"
#endif
#ifndef SC_XIROOT_HXX
#include "xiroot.hxx"
#endif

class ScMatrix;

// Byte/Unicode strings =======================================================

/** This class represents an unformatted or formatted string and provides importing from stream. */
class XclImpString
{
private:
    String                      maString;       /// The text data of the string.
    XclFormatRunVec             maFormats;      /// All formatting runs.

public:
    /** Constructs an unformatted string. */
    explicit                    XclImpString( const String& rString );
    /** Constructs a formatted string by reading completely from stream. */
    explicit                    XclImpString( XclImpStream& rStrm, XclStrFlags nFlags = EXC_STR_DEFAULT );

                                ~XclImpString();

    /** Insert a formatting run to the format buffer. */
    void                        AppendFormat( sal_uInt16 nChar, sal_uInt16 nFontIx );
    /** Reads and appends the formatting information (run count and runs) from stream. */
    void                        ReadFormats( XclImpStream& rStrm );
    /** Reads and appends nRunCount formatting runs from stream. */
    void                        ReadFormats( XclImpStream& rStrm, sal_uInt16 nRunCount );

    /** Returns the pure text data of the string. */
    inline const String&        GetText() const { return maString; }
    /** Returns true, if the string contains formatting information. */
    inline bool                 IsRich() const { return !maFormats.empty(); }
    /** Returns the formatting run vector. */
    inline const XclFormatRunVec& GetFormats() const { return maFormats; }
};

// String->EditEngine conversion ==============================================

class ScBaseCell;
class EditTextObject;

/** This class provides methods to convert an XclImpString.
    @The string can be converted to an edit engine text object or directly
    to a Calc edit cell. */
class XclImpStringHelper : ScfNoInstance
{
public:
    /** Returns a new edit engine text object.
        @param nXFIndex  Index to XF for first text portion (for escapement). */
    static EditTextObject*      CreateTextObject(
                                    const XclImpRoot& rRoot,
                                    const XclImpString& rString,
                                    sal_uInt32 nXFIndex = 0 );

    /** Creates a new text cell or edit cell for a Calc document.
        @param nXFIndex  Index to XF for first text portion (for escapement). */
    static ScBaseCell*          CreateCell(
                                    const XclImpRoot& rRoot,
                                    const XclImpString& rString,
                                    sal_uInt32 nXFIndex = 0 );
};

// Header/footer conversion ===================================================

class EditEngine;
class EditTextObject;
class SfxItemSet;
class SvxFieldItem;
struct XclFontData;

/** Converts an Excel header/footer string into three edit engine text objects.
    @descr  Header/footer content is divided into three parts: Left, center and
    right portion. All formatting information is encoded in the Excel string
    using special character seuences. A control sequence starts with the ampersand
    character.

    Supported control sequences:
    &L                      start of left portion
    &C                      start of center portion
    &R                      start of right portion
    &P                      current page number
    &N                      page count
    &D                      current date
    &T                      current time
    &A                      table name
    &F                      file name without path (see also &Z&F)
    &Z                      file path without file name (converted to full file name, see also &Z&F)
    &Z&F                    file path and name
    &U                      underlining on/off
    &E                      double underlining on/off
    &S                      strikeout characters on/off
    &X                      superscript on/off
    &Y                      subscript on/off
    &"fontname,fontstyle"   use font with name 'fontname' and style 'fontstyle'
    &fontheight             set font height in points ('fontheight' is a decimal value)

    Known but unsupported control sequences:
    &G                      picture
 */
class XclImpHFConverter : protected XclImpRoot, ScfNoCopy
{
private:
    typedef ::std::auto_ptr< EditTextObject >   EditTextObjectPtr;
    typedef ::std::auto_ptr< XclFontData >      XclFontDataPtr;

    EditEngine&                 mrEE;           /// The header/footer edit engine.
    EditTextObjectPtr           mppObjs[ 3 ];   /// Edit engine text objects for all portions.
    ESelection                  mpSels[ 3 ];    /// Edit engine selections for all portions.
    String                      maCurrText;     /// Current text to insert into edit engine.
    XclFontDataPtr              mpFontData;     /// Font data of current text.
    sal_uInt16                  mnCurrObj;      /// The current portion.

public:
    explicit                    XclImpHFConverter( const XclImpRoot& rRoot );
                                ~XclImpHFConverter();

    /** Parses the passed string and creates three new edit engine text objects. */
    void                        ParseString( const String& rHFString );

    /** Creates a ScPageHFItem and inserts it into the passed item set. */
    void                        FillToItemSet( SfxItemSet& rItemSet, sal_uInt16 nWhichId );

private:
    /** Returns the current edit engine text object. */
    inline EditTextObjectPtr&   GetCurrObj() { return mppObjs[ mnCurrObj ]; }
    /** Returns the current selection. */
    inline ESelection&          GetCurrSel() { return mpSels[ mnCurrObj ]; }

    /** Sets the font attributes at the current selection.
        @descr  After that, the start position of the current selection object is
        adjusted to the end of the selection. */
    void                        SetAttribs();
    /** Resets font data to application default font. */
    void                        ResetFontData();

    /** Inserts maCurrText into edit engine and adjusts the current selection object.
        @descr  The text shall not contain a newline character.
        The text will be cleared after insertion. */
    void                        InsertText();
    /** Inserts a line break and adjusts the current selection object. */
    void                        InsertLineBreak();
    /** Inserts the passed text field and adjusts the current selection object. */
    void                        InsertField( const SvxFieldItem& rFieldItem );

    /** Creates the edit engine text object of current portion from edit engine. */
    void                        CreateCurrObject();
    /** Changes current header/footer portion to eNew.
        @descr  Creates text object of current portion and reinitializes edit engine. */
    void                        SetNewPortion( sal_uInt16 nNew );
};

// URL conversion =============================================================

/** This class contains static methods to decode an URL stored in an Excel file.
    @descr  Excel URLs can contain a sheet name, for instance: path\[test.xls]Sheet1
    This sheet name will be extracted automatically. */
class XclImpUrlHelper : ScfNoInstance
{
public:
    /** Decodes an encoded external document URL with optional sheet name.
        @param rUrl  Returns the decoded file name incl. path.
        @param rTabName  Returns the decoded sheet name.
        @param rbSameWb  Returns true, if the URL is a reference to the own workbook.
        @param rEncodedUrl   An encoded URL from Excel. */
    static void                 DecodeUrl(
                                    String& rUrl,
                                    String& rTabName,
                                    bool& rbSameWb,
                                    const XclImpRoot& rRoot,
                                    const String& rEncodedUrl );

    /** Decodes an encoded external document URL without sheet name.
        @param rUrl  Returns the decoded file name incl. path.
        @param rbSameWb  Returns true, if the URL is a reference to the own workbook.
        @param rEncodedUrl   An encoded URL from Excel. */
    static void                 DecodeUrl(
                                    String& rUrl,
                                    bool& rbSameWb,
                                    const XclImpRoot& rRoot,
                                    const String& rEncodedUrl );

    /** Decodes the passed URL to OLE or DDE link components.
        @descr  For DDE links: Decodes to application name and topic.
        For OLE object links: Decodes to class name and document URL.
        @return  true = decoding was successful, returned strings are valid (not empty). */
    static bool                 DecodeLink( String& rApplic, String& rTopic, const String rEncUrl );
};

// Cached Values ==============================================================

class ScTokenArray;

/** This class stores one cached value of a cached value list (used for instance in
    CRN, EXTERNNAME, tArray). */
class XclImpCachedValue : ScfNoCopy
{
protected:
    typedef ::std::auto_ptr< String >               StringPtr;
    typedef ::std::auto_ptr< const ScTokenArray >   ScTokenArrayPtr;

    StringPtr                   mpStr;      /// Cached value is a string.
    double                      mfValue;    /// Cached value is a double.
    ScTokenArrayPtr             mpTokArr;   /// Cached value is a formula or error code or Boolean.
    sal_uInt8                   mnBoolErr;  /// Boolean value or Excel error code.
    sal_uInt8                   mnType;     /// The type of the cached value (EXC_CACHEDVAL_*).

public:
    /** Creates a cached value and reads contents from stream and stores it with its array address. */
    explicit                    XclImpCachedValue( XclImpStream& rStrm );
    virtual                     ~XclImpCachedValue();

    /** Returns the type of the cached value (EXC_CACHEDVAL_*). */
    inline sal_uInt8            GetType() const     { return mnType; }
    /** Returns the cached string value, if this value is a string, else an empty string. */
    inline const String&        GetString() const   { return mpStr.get() ? *mpStr : EMPTY_STRING; }
    /** Returns the cached number, if this value has number type, else 0.0. */
    inline double               GetValue() const    { return mfValue; }
    /** Returns the cached Boolean value, if this value has Boolean type, else false. */
    inline bool                 GetBool() const     { return (mnType == EXC_CACHEDVAL_BOOL) && (mnBoolErr != 0); }
    /** Returns the cached Calc error code, if this value has Error type, else 0. */
    USHORT                      GetError() const;
    /** Returns the token array if this is a Boolean value or error value, else 0. */
    inline const ScTokenArray*  GetBoolErrFmla() const { return mpTokArr.get(); }
};

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

/** Contains cached values in a 2-dimensional array. */
class XclImpCachedMatrix
{
public:
    explicit                    XclImpCachedMatrix( XclImpStream& rStrm );
                                ~XclImpCachedMatrix();

    /** Creates a new ScMatrix object and fills it with the contained values. */
    ScMatrixRef                 CreateScMatrix() const;

private:
    typedef ScfDelList< XclImpCachedValue > XclImpValueList;

    XclImpValueList             maValueList;    /// List of cached cell values.
    USHORT                      mnScCols;       /// Number of cached columns.
    USHORT                      mnScRows;       /// Number of cached rows.

};

// ============================================================================

#endif

<|endoftext|>


<commit_before><commit_msg>More reduction of scoping inside for loop.<commit_after><|endoftext|>