<commit_before>#include "LargeRAWFile.h"

using namespace std;

#define BLOCK_COPY_SIZE (UINT64(128*1024*1024))

LargeRAWFile::LargeRAWFile(const std::string& strFilename, UINT64 iHeaderSize) :
  m_strFilename(strFilename),
  m_bIsOpen(false),
  m_bWritable(false),
  m_iHeaderSize(iHeaderSize)
{
}

LargeRAWFile::LargeRAWFile(const std::wstring& wstrFilename, UINT64 iHeaderSize) :
  m_bIsOpen(false),
  m_bWritable(false),
  m_iHeaderSize(iHeaderSize)
{
  string strFilename(wstrFilename.begin(), wstrFilename.end());
  m_strFilename = strFilename;
}

LargeRAWFile::LargeRAWFile(LargeRAWFile &other) :
  m_strFilename(other.m_strFilename+"~"),
  m_bIsOpen(other.m_bIsOpen),
  m_iHeaderSize(other.m_iHeaderSize)
{
  if (m_bIsOpen) {
    UINT64 iDataSize = other.GetCurrentSize();
    Create(iDataSize);

    other.SeekStart();

    unsigned char* pData = new unsigned char[size_t(min(iDataSize, BLOCK_COPY_SIZE))];
    for (UINT64 i = 0;i<iDataSize;i+=BLOCK_COPY_SIZE) {
      UINT64 iCopySize = min(BLOCK_COPY_SIZE, iDataSize-i);

      other.ReadRAW(pData, iCopySize);
      WriteRAW(pData, iCopySize);
    }
    delete [] pData;
  }
}

bool LargeRAWFile::Open(bool bReadWrite) {
  #ifdef _WIN32
    m_StreamFile = CreateFileA(m_strFilename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    m_bIsOpen = m_StreamFile != INVALID_HANDLE_VALUE;
  #else
    m_StreamFile = fopen(m_strFilename.c_str(), (bReadWrite) ? "w+b" : "rb");
    m_bIsOpen = m_StreamFile != NULL;
  #endif

  if (m_bIsOpen && m_iHeaderSize != 0) SeekStart();

  m_bWritable = (m_bIsOpen) ? bReadWrite : false;

  return m_bIsOpen;
}

bool LargeRAWFile::Create(UINT64 iInitialSize) {
#ifdef _WIN32
  m_StreamFile = CreateFileA(m_strFilename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
  m_bIsOpen = m_StreamFile != INVALID_HANDLE_VALUE;
#else
  m_StreamFile = fopen(m_strFilename.c_str(), "w+b");
  m_bIsOpen = m_StreamFile != NULL;
#endif

  if (m_bIsOpen) {
    SeekPos(iInitialSize);
    SeekStart();
  }

  return m_bIsOpen;
}

void LargeRAWFile::Close() {
  if (m_bIsOpen) {
    #ifdef _WIN32
        CloseHandle(m_StreamFile);
    #else
      fclose(m_StreamFile);
    #endif
    m_bIsOpen =false;
  }
}

UINT64 LargeRAWFile::GetCurrentSize() {
  UINT64 iPrevPos = GetPos();

  SeekStart();
  UINT64 ulStart = GetPos();
  UINT64 ulEnd   = SeekEnd();
  UINT64 ulFileLength = ulEnd - ulStart;

  SeekPos(iPrevPos);

  return ulFileLength;
}

void LargeRAWFile::SeekStart(){
  SeekPos(0);
}

UINT64 LargeRAWFile::SeekEnd(){
  #ifdef _WIN32
    LARGE_INTEGER liTarget, liRealTarget; liTarget.QuadPart = 0;
    SetFilePointerEx(m_StreamFile, liTarget, &liRealTarget, FILE_END);
    return UINT64(liRealTarget.QuadPart)-m_iHeaderSize;
  #else
    if(fseeko(m_StreamFile, 0, SEEK_END)==0)
      return ftello(m_StreamFile)-m_iHeaderSize;//get current position=file size!
    else
      return 0;
  #endif
}

UINT64 LargeRAWFile::GetPos(){
  #ifdef _WIN32
    LARGE_INTEGER liTarget, liRealTarget; liTarget.QuadPart = 0;
    SetFilePointerEx(m_StreamFile, liTarget, &liRealTarget, FILE_CURRENT);
    return UINT64(liRealTarget.QuadPart)-m_iHeaderSize;
  #else
      return ftello(m_StreamFile)-m_iHeaderSize;//get current position=file size!
  #endif
}

void LargeRAWFile::SeekPos(UINT64 iPos){
  #ifdef _WIN32
    LARGE_INTEGER liTarget; liTarget.QuadPart = LONGLONG(iPos+m_iHeaderSize);
    SetFilePointerEx(m_StreamFile, liTarget, NULL, FILE_BEGIN);
  #else
    fseeko(m_StreamFile, off_t(iPos+m_iHeaderSize), SEEK_SET);
  #endif
}

size_t LargeRAWFile::ReadRAW(unsigned char* pData, UINT64 iCount){
  #ifdef _WIN32
    DWORD dwReadBytes;
    ReadFile(m_StreamFile, pData, DWORD(iCount), &dwReadBytes, NULL);
    return dwReadBytes;
  #else
    return fread(pData,1,iCount,m_StreamFile);
  #endif
}

size_t LargeRAWFile::WriteRAW(const unsigned char* pData, UINT64 iCount){
  #ifdef _WIN32
    DWORD dwWrittenBytes;
    WriteFile(m_StreamFile, pData, DWORD(iCount), &dwWrittenBytes, NULL);
    return dwWrittenBytes;
  #else
    return fwrite(pData,1,iCount,m_StreamFile);
  #endif
}

void LargeRAWFile::Delete() {
  if (m_bIsOpen) Close();
  remove(m_strFilename.c_str());
}
<commit_msg>Potential uninitialized var: copy writable flag from source.<commit_after>#include "LargeRAWFile.h"

using namespace std;

#define BLOCK_COPY_SIZE (UINT64(128*1024*1024))

LargeRAWFile::LargeRAWFile(const std::string& strFilename, UINT64 iHeaderSize) :
  m_strFilename(strFilename),
  m_bIsOpen(false),
  m_bWritable(false),
  m_iHeaderSize(iHeaderSize)
{
}

LargeRAWFile::LargeRAWFile(const std::wstring& wstrFilename, UINT64 iHeaderSize) :
  m_bIsOpen(false),
  m_bWritable(false),
  m_iHeaderSize(iHeaderSize)
{
  string strFilename(wstrFilename.begin(), wstrFilename.end());
  m_strFilename = strFilename;
}

LargeRAWFile::LargeRAWFile(LargeRAWFile &other) :
  m_strFilename(other.m_strFilename+"~"),
  m_bIsOpen(other.m_bIsOpen),
  m_iHeaderSize(other.m_iHeaderSize),
  m_bWritable(other.m_bWritable)
{
  if (m_bIsOpen) {
    UINT64 iDataSize = other.GetCurrentSize();
    Create(iDataSize);

    other.SeekStart();

    unsigned char* pData = new unsigned char[size_t(min(iDataSize, BLOCK_COPY_SIZE))];
    for (UINT64 i = 0;i<iDataSize;i+=BLOCK_COPY_SIZE) {
      UINT64 iCopySize = min(BLOCK_COPY_SIZE, iDataSize-i);

      other.ReadRAW(pData, iCopySize);
      WriteRAW(pData, iCopySize);
    }
    delete [] pData;
  }
}

bool LargeRAWFile::Open(bool bReadWrite) {
  #ifdef _WIN32
    m_StreamFile = CreateFileA(m_strFilename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    m_bIsOpen = m_StreamFile != INVALID_HANDLE_VALUE;
  #else
    m_StreamFile = fopen(m_strFilename.c_str(), (bReadWrite) ? "w+b" : "rb");
    m_bIsOpen = m_StreamFile != NULL;
  #endif

  if (m_bIsOpen && m_iHeaderSize != 0) SeekStart();

  m_bWritable = (m_bIsOpen) ? bReadWrite : false;

  return m_bIsOpen;
}

bool LargeRAWFile::Create(UINT64 iInitialSize) {
#ifdef _WIN32
  m_StreamFile = CreateFileA(m_strFilename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
  m_bIsOpen = m_StreamFile != INVALID_HANDLE_VALUE;
#else
  m_StreamFile = fopen(m_strFilename.c_str(), "w+b");
  m_bIsOpen = m_StreamFile != NULL;
#endif

  if (m_bIsOpen) {
    SeekPos(iInitialSize);
    SeekStart();
  }

  return m_bIsOpen;
}

void LargeRAWFile::Close() {
  if (m_bIsOpen) {
    #ifdef _WIN32
        CloseHandle(m_StreamFile);
    #else
      fclose(m_StreamFile);
    #endif
    m_bIsOpen =false;
  }
}

UINT64 LargeRAWFile::GetCurrentSize() {
  UINT64 iPrevPos = GetPos();

  SeekStart();
  UINT64 ulStart = GetPos();
  UINT64 ulEnd   = SeekEnd();
  UINT64 ulFileLength = ulEnd - ulStart;

  SeekPos(iPrevPos);

  return ulFileLength;
}

void LargeRAWFile::SeekStart(){
  SeekPos(0);
}

UINT64 LargeRAWFile::SeekEnd(){
  #ifdef _WIN32
    LARGE_INTEGER liTarget, liRealTarget; liTarget.QuadPart = 0;
    SetFilePointerEx(m_StreamFile, liTarget, &liRealTarget, FILE_END);
    return UINT64(liRealTarget.QuadPart)-m_iHeaderSize;
  #else
    if(fseeko(m_StreamFile, 0, SEEK_END)==0)
      return ftello(m_StreamFile)-m_iHeaderSize;//get current position=file size!
    else
      return 0;
  #endif
}

UINT64 LargeRAWFile::GetPos(){
  #ifdef _WIN32
    LARGE_INTEGER liTarget, liRealTarget; liTarget.QuadPart = 0;
    SetFilePointerEx(m_StreamFile, liTarget, &liRealTarget, FILE_CURRENT);
    return UINT64(liRealTarget.QuadPart)-m_iHeaderSize;
  #else
      return ftello(m_StreamFile)-m_iHeaderSize;//get current position=file size!
  #endif
}

void LargeRAWFile::SeekPos(UINT64 iPos){
  #ifdef _WIN32
    LARGE_INTEGER liTarget; liTarget.QuadPart = LONGLONG(iPos+m_iHeaderSize);
    SetFilePointerEx(m_StreamFile, liTarget, NULL, FILE_BEGIN);
  #else
    fseeko(m_StreamFile, off_t(iPos+m_iHeaderSize), SEEK_SET);
  #endif
}

size_t LargeRAWFile::ReadRAW(unsigned char* pData, UINT64 iCount){
  #ifdef _WIN32
    DWORD dwReadBytes;
    ReadFile(m_StreamFile, pData, DWORD(iCount), &dwReadBytes, NULL);
    return dwReadBytes;
  #else
    return fread(pData,1,iCount,m_StreamFile);
  #endif
}

size_t LargeRAWFile::WriteRAW(const unsigned char* pData, UINT64 iCount){
  #ifdef _WIN32
    DWORD dwWrittenBytes;
    WriteFile(m_StreamFile, pData, DWORD(iCount), &dwWrittenBytes, NULL);
    return dwWrittenBytes;
  #else
    return fwrite(pData,1,iCount,m_StreamFile);
  #endif
}

void LargeRAWFile::Delete() {
  if (m_bIsOpen) Close();
  remove(m_strFilename.c_str());
}
<|endoftext|>


<commit_before>#ifndef MYPARSER_AST_HPP
#define MYPARSER_AST_HPP

#include "myparser_str.hpp"
#include "myparser_pass.hpp"

namespace myparser {

using Input = std::string::const_iterator;

using BuiltinRoot = MP_STR("root", 4);
using BuiltinSpace = MP_STR("space", 5);
using BuiltinKeyword = MP_STR("keyword", 7);
using BuiltinError = MP_STR("error", 5);

template <class TX = void> // actually not a template
class Node {
private:
    const Input pos;

    inline Node() = delete;

protected:
    inline Node(
        const Input &input
    ): pos(input) {}

public:
    virtual ~Node() {} // destructable (public)

    virtual void free() {
        delete this;
    }

    virtual bool empty() const = 0;

    virtual void runPass(PassBase<> *pass) const = 0;

    virtual const std::string &getRuleName() const = 0;

    virtual size_t getLen() const = 0;

    virtual void getFullText(std::ostream &out) const = 0;

    inline const std::string asFullText() const {
        std::ostringstream result;

        getFullText(result);

        return result.str();
    }

    inline const Input &getPos() const {
        return pos;
    }

    inline const Input getTail() const {
        return pos + getLen();
    }

    inline Node<> *challengeLonger(Node<> *target) {
        if (!target) {
            return this;
        }

        if (getTail() > target->getTail()) {
            target->free();
            return this;
        } else {
            this->free();
            return target;
        }
    }
};

template <class TX = void> // actually not a template
class NodeList: public Node<> {
private:
    std::vector<Node<> *> children;

    size_t basepos;
    NodeList<> *brother = nullptr;

protected:
    inline NodeList(
        const Input &input
    ): Node<>(input), children() {}

public:
    virtual ~NodeList() {
        for (size_t i = basepos; i < children.size(); ++i) {
            children[i]->free();
        }
    }

    virtual void free() {
        if (brother) {
            brother->basepos = 0;
            brother->brother = nullptr;
        }
        delete this;
    }

    virtual bool empty() const {
        for (Node<> *child: children) {
            if (!child->empty()) {
                return false;
            }
        }

        return true;
    }

    inline void bind(NodeList<> *target, const size_t pos) {
        brother = target;
        basepos = pos;
    }

    inline void putChild(Node<> *value) {
        children.push_back(value);
    }

    virtual size_t getLen() const {
        size_t result = 0;

        for (Node<> *child: children) {
            result += child->getLen();
        }

        return result;
    }

    virtual void getFullText(std::ostream &out) const {
        for (Node<> *child: children) {
            child->getFullText(out);
        }
    }

    inline const std::vector<Node<> *> &getChildren() const {
        return children;
    }
};

template <size_t I>
class NodeListIndexed: public NodeList<> {
public:
    inline NodeListIndexed(
        const Input &input
    ): NodeList<>(input) {}

    // virtual ~NodeListIndexed() {}

    inline size_t getIndex() const {
        return I;
    }
};

template <class TX = void> // actually not a template
class NodeText: public Node<> {
private:
    const std::string text;

protected:
    inline NodeText(
        const Input &input, std::string &&value
    ): Node<>(input), text(std::move(value)) {}

    inline NodeText(
        const Input &input, const std::string &value
    ): Node<>(input), text(value) {}

public:
    // virtual ~NodeText() {}

    virtual bool accepted() const {
        return true;
    }

    virtual bool empty() const {
        return accepted() && text.size() == 0;
    }

    virtual size_t getLen() const {
        return text.size();
    }

    virtual void getFullText(std::ostream &out) const {
        out << text;
    }

    inline const std::string &getText() const {
        return text;
    }
};

template <class TX = void> // actually not a template
class NodeTextPure: public NodeText<> {
public:
    inline NodeTextPure(
        const Input &input, std::string &&value
    ): NodeText<>(input, std::move(value)) {}

    // virtual ~NodeTextPure() {}
};

template <class E>
class NodeTextOrError: public NodeText<> {
public:
    inline NodeTextOrError(
        const Input &input, std::string &&value
    ): NodeText<>(input, std::move(value)) {}

    // virtual ~NodeTextOrError() {}
};

template <class E>
class NodeError: public Node<> {
public:
    inline NodeError(
        const Input &input
    ): Node<>(input) {}

    // virtual ~NodeError() {}

    virtual bool empty() const {
        return false;
    }

    virtual size_t getLen() const {
        return 0;
    }

    virtual void getFullText(std::ostream &out) const {
        // nothing
        (void) out;
    }
};

// could specialize
template <class N>
class NodeBaseList {
public:
    template <size_t I>
    using Type = NodeListIndexed<I>;
};

// could specialize
template <class N>
class NodeBaseText {
public:
    template <class TX = void> // actually not a template
    using Type = NodeTextPure<>;
};

// could specialize
template <class N>
class NodeBaseError {
public:
    template <class E>
    using Type = NodeError<E>;
};

template <class N, class T, size_t I = 0 /* bind later */>
class NodeTyped: public T {
public:
    using T::T;

    virtual void runPass(PassBase<> *pass) const {
        Pass<I>::call(pass, pass->getId(), this);
    }

    virtual const std::string &getRuleName() const {
        return N::getStr();
    }
};

template <class N, size_t I>
using NodeTypedList = NodeTyped<N, typename NodeBaseList<N>::template Type<I>>;

template <class N>
using NodeTypedText = NodeTyped<N, typename NodeBaseText<N>::template Type<>>;

template <class N, class E>
using NodeTypedError = NodeTyped<N, typename NodeBaseError<N>::template Type<E>>;

}

#endif
<commit_msg>simplify getTail()<commit_after>#ifndef MYPARSER_AST_HPP
#define MYPARSER_AST_HPP

#include "myparser_str.hpp"
#include "myparser_pass.hpp"

namespace myparser {

using Input = std::string::const_iterator;

using BuiltinRoot = MP_STR("root", 4);
using BuiltinSpace = MP_STR("space", 5);
using BuiltinKeyword = MP_STR("keyword", 7);
using BuiltinError = MP_STR("error", 5);

template <class TX = void> // actually not a template
class Node {
private:
    inline Node() = delete;

protected:
    inline Node(
        const Input &input
    ): pos(input), tail(input) {}

    const Input pos;
    Input tail;

public:
    virtual ~Node() {} // destructable (public)

    virtual void free() {
        delete this;
    }

    virtual bool empty() const = 0;

    virtual void runPass(PassBase<> *pass) const = 0;

    virtual const std::string &getRuleName() const = 0;

    virtual void getFullText(std::ostream &out) const = 0;

    inline const std::string asFullText() const {
        std::ostringstream result;

        getFullText(result);

        return result.str();
    }

    inline const Input &getPos() const {
        return pos;
    }

    inline const Input &getTail() const {
        return tail;
    }

    inline Node<> *challengeLonger(Node<> *target) {
        if (!target) {
            return this;
        }

        if (getTail() > target->getTail()) {
            target->free();
            return this;
        } else {
            this->free();
            return target;
        }
    }
};

template <class TX = void> // actually not a template
class NodeList: public Node<> {
private:
    std::vector<Node<> *> children;

    size_t basepos;
    NodeList<> *brother = nullptr;

protected:
    inline NodeList(
        const Input &input
    ): Node<>(input), children() {}

public:
    virtual ~NodeList() {
        for (size_t i = basepos; i < children.size(); ++i) {
            children[i]->free();
        }
    }

    virtual void free() {
        if (brother) {
            brother->basepos = 0;
            brother->brother = nullptr;
        }
        delete this;
    }

    virtual bool empty() const {
        for (Node<> *child: children) {
            if (!child->empty()) {
                return false;
            }
        }

        return true;
    }

    inline void bind(NodeList<> *target, const size_t pos) {
        brother = target;
        basepos = pos;
    }

    inline void putChild(Node<> *value) {
        children.push_back(value);
        tail = value->getTail();
    }

    virtual void getFullText(std::ostream &out) const {
        for (Node<> *child: children) {
            child->getFullText(out);
        }
    }

    inline const std::vector<Node<> *> &getChildren() const {
        return children;
    }
};

template <size_t I>
class NodeListIndexed: public NodeList<> {
public:
    inline NodeListIndexed(
        const Input &input
    ): NodeList<>(input) {}

    // virtual ~NodeListIndexed() {}

    inline size_t getIndex() const {
        return I;
    }
};

template <class TX = void> // actually not a template
class NodeText: public Node<> {
private:
    const std::string text;

protected:
    inline NodeText(
        const Input &input, std::string &&value
    ): Node<>(input), text(std::move(value)) {
        tail = tail + text.size();
    }

    inline NodeText(
        const Input &input, const std::string &value
    ): Node<>(input), text(value) {
        tail = tail + text.size();
    }

public:
    // virtual ~NodeText() {}

    virtual bool accepted() const {
        return true;
    }

    virtual bool empty() const {
        return accepted() && text.size() == 0;
    }

    virtual void getFullText(std::ostream &out) const {
        out << text;
    }

    inline const std::string &getText() const {
        return text;
    }
};

template <class TX = void> // actually not a template
class NodeTextPure: public NodeText<> {
public:
    inline NodeTextPure(
        const Input &input, std::string &&value
    ): NodeText<>(input, std::move(value)) {}

    // virtual ~NodeTextPure() {}
};

template <class E>
class NodeTextOrError: public NodeText<> {
public:
    inline NodeTextOrError(
        const Input &input, std::string &&value
    ): NodeText<>(input, std::move(value)) {}

    // virtual ~NodeTextOrError() {}
};

template <class E>
class NodeError: public Node<> {
public:
    inline NodeError(
        const Input &input
    ): Node<>(input) {}

    // virtual ~NodeError() {}

    virtual bool empty() const {
        return false;
    }

    virtual void getFullText(std::ostream &out) const {
        // nothing
        (void) out;
    }
};

// could specialize
template <class N>
class NodeBaseList {
public:
    template <size_t I>
    using Type = NodeListIndexed<I>;
};

// could specialize
template <class N>
class NodeBaseText {
public:
    template <class TX = void> // actually not a template
    using Type = NodeTextPure<>;
};

// could specialize
template <class N>
class NodeBaseError {
public:
    template <class E>
    using Type = NodeError<E>;
};

template <class N, class T, size_t I = 0 /* bind later */>
class NodeTyped: public T {
public:
    using T::T;

    virtual void runPass(PassBase<> *pass) const {
        Pass<I>::call(pass, pass->getId(), this);
    }

    virtual const std::string &getRuleName() const {
        return N::getStr();
    }
};

template <class N, size_t I>
using NodeTypedList = NodeTyped<N, typename NodeBaseList<N>::template Type<I>>;

template <class N>
using NodeTypedText = NodeTyped<N, typename NodeBaseText<N>::template Type<>>;

template <class N, class E>
using NodeTypedError = NodeTyped<N, typename NodeBaseError<N>::template Type<E>>;

}

#endif
<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef XENSTORE_HH_
#define XENSTORE_HH_

extern "C" {
    #include <xenstore.h>
}

class xenstore {
public:
    class xenstore_transaction {
    private:
        xenstore *_x;
    protected:
        xs_transaction_t _t = 0;
    public:
        explicit xenstore_transaction(xenstore *x) : _x(x)
                                                   , _t(x->start_transaction()) {}
        explicit xenstore_transaction() {}

        ~xenstore_transaction() { if (_t) { _x->end_transaction(_t);  } }

        xs_transaction_t t() { return _t; }
        friend class xenstore;
    };

protected:
    xs_transaction_t start_transaction();
    void end_transaction(xs_transaction_t t);

    static xenstore_transaction _xs_null; // having it here simplify forward decls

private:
    static xenstore *_instance;
    struct xs_handle *_h;
    explicit xenstore();
    ~xenstore();

public:
    static xenstore *instance();

    virtual void write(std::string path, std::string value, xenstore_transaction &t = _xs_null);
    virtual void remove(std::string path, xenstore_transaction &t = _xs_null);

    virtual std::string read(std::string path, xenstore_transaction &t = _xs_null);

    virtual std::list<std::string> ls(std::string path, xenstore_transaction &t = _xs_null);
    template <typename T>
    T read(std::string path, xenstore_transaction &t = _xs_null) { return boost::lexical_cast<T>(read(path, t)); }
    template <typename T>
    T read_or_default(std::string path, T deflt = T(), xenstore_transaction &t = _xs_null) {
        auto val = read(path, t);
        if (val.empty()) {
            return deflt;
        } else {
            return boost::lexical_cast<T>(val);
        }
    }

    template <typename T>
    void write(std::string path, T val, xenstore_transaction &t = _xs_null) { return write(path, std::to_string(val), t); }
};

#endif /* XENSTORE_HH_ */
<commit_msg>fix xenstore compilation<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef XENSTORE_HH_
#define XENSTORE_HH_

#include <list>

extern "C" {
    #include <xenstore.h>
}

class xenstore {
public:
    class xenstore_transaction {
    private:
        xenstore *_x;
    protected:
        xs_transaction_t _t = 0;
    public:
        explicit xenstore_transaction(xenstore *x) : _x(x)
                                                   , _t(x->start_transaction()) {}
        explicit xenstore_transaction() {}

        ~xenstore_transaction() { if (_t) { _x->end_transaction(_t);  } }

        xs_transaction_t t() { return _t; }
        friend class xenstore;
    };

protected:
    xs_transaction_t start_transaction();
    void end_transaction(xs_transaction_t t);

    static xenstore_transaction _xs_null; // having it here simplify forward decls

private:
    static xenstore *_instance;
    struct xs_handle *_h;
    explicit xenstore();
    ~xenstore();

public:
    static xenstore *instance();

    virtual void write(std::string path, std::string value, xenstore_transaction &t = _xs_null);
    virtual void remove(std::string path, xenstore_transaction &t = _xs_null);

    virtual std::string read(std::string path, xenstore_transaction &t = _xs_null);

    virtual std::list<std::string> ls(std::string path, xenstore_transaction &t = _xs_null);
    template <typename T>
    T read(std::string path, xenstore_transaction &t = _xs_null) { return boost::lexical_cast<T>(read(path, t)); }
    template <typename T>
    T read_or_default(std::string path, T deflt = T(), xenstore_transaction &t = _xs_null) {
        auto val = read(path, t);
        if (val.empty()) {
            return deflt;
        } else {
            return boost::lexical_cast<T>(val);
        }
    }

    template <typename T>
    void write(std::string path, T val, xenstore_transaction &t = _xs_null) { return write(path, std::to_string(val), t); }
};

#endif /* XENSTORE_HH_ */
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWin32TextMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to Matt Turek who developed this class.

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkWin32TextMapper.h"
#include "vtkWin32ImageWindow.h"

int vtkWin32TextMapper::GetCompositingMode(vtkActor2D* actor)
{
  vtkProperty2D* tempProp = actor->GetProperty();
  int compositeMode = tempProp->GetCompositingOperator();

  switch (compositeMode)
  {
  case VTK_BLACK:
	  return R2_BLACK;
	  break;
  case VTK_NOT_DEST:
	  return R2_NOT;
	  break;
  case VTK_SRC_AND_DEST:
	  return R2_MASKPEN;
	  break;
  case VTK_SRC_OR_DEST:
	  return  R2_MERGEPEN;
	  break;
  case VTK_NOT_SRC:
	  return R2_NOTCOPYPEN;
	  break;
  case VTK_SRC_XOR_DEST:
	  return R2_XORPEN;
      break;
  case VTK_SRC_AND_notDEST:
	  return R2_MASKPENNOT;
	  break;
  case VTK_SRC:
	  return R2_COPYPEN;
	  break;
  case VTK_WHITE:
	  return R2_WHITE;
	  break;
  default:
	  return R2_COPYPEN;
	  break;
  }

}

void vtkWin32TextMapper::Render(vtkViewport* viewport, vtkActor2D* actor)
{

  vtkDebugMacro (<< "vtkWin32TextMapper::Render");

  // Check for input
  if (this->Input == NULL)
    {
    vtkErrorMacro (<<"vtkWin32TextMapper::Render - No input");
    }

  // Get the window information for display
  vtkWindow*  window = viewport->GetVTKWindow();
  HWND windowId = (HWND) window->GetGenericWindowId();

  // Get the device context from the window

  HDC hdc = (HDC) window->GetGenericContext();

  // Get the position of the text actor
  POINT ptDestOff;
  int xOffset = 0;
  int yOffset = 0;

  // Get the position of the text actor
  int* actorPos =
    actor->GetPositionCoordinate()->GetComputedLocalDisplayValue(viewport);
  xOffset = actorPos[0];
  yOffset = actorPos[1];

  ptDestOff.x = xOffset;
  ptDestOff.y = yOffset;

  // Set up the font color from the text actor
  unsigned char red = 0;
  unsigned char green = 0;
  unsigned char blue = 0;
  float*  actorColor = actor->GetProperty()->GetColor();
  red = (unsigned char) (actorColor[0] * 255.0);
  green = (unsigned char) (actorColor[1] * 255.0);
  blue = (unsigned char) (actorColor[2] * 255.0);

  // Set up the shadow color
  float intensity;
  intensity = (red + green + blue)/3.0;

  unsigned char shadowRed, shadowGreen, shadowBlue;
  if (intensity > 128)
    {
    shadowRed = shadowBlue = shadowGreen = 0;
    }
  else
    {
    shadowRed = shadowBlue = shadowGreen = 255;
    }

  // Create the font
  LOGFONT fontStruct;
  char fontname[32];
  DWORD family;
  switch (this->FontFamily)
    {
    case VTK_ARIAL:
      strcpy(fontname, "Arial");
	  family = FF_SWISS;
	  break;
	case VTK_TIMES:
      strcpy(fontname, "Times Roman");
	  family = FF_ROMAN;
	  break;
	case VTK_COURIER:
      strcpy(fontname, "Courier");
	  family = FF_MODERN;
	  break;
	default:
      strcpy(fontname, "Arial");
	  family = FF_SWISS;
	  break;
    }

  fontStruct.lfHeight = MulDiv(this->FontSize,
			       GetDeviceCaps(hdc, LOGPIXELSY), 72);
  // height in logical units
  fontStruct.lfWidth = 0;  // default width
  fontStruct.lfEscapement = 0;
  fontStruct.lfOrientation = 0;
  if (this->Bold == 1)
    {
    fontStruct.lfWeight = FW_BOLD;
    }
  else
    {
    fontStruct.lfWeight = FW_NORMAL;
    }
  fontStruct.lfItalic = this->Italic;
  fontStruct.lfUnderline = 0;
  fontStruct.lfStrikeOut = 0;
  fontStruct.lfCharSet = ANSI_CHARSET;
  fontStruct.lfOutPrecision = OUT_DEFAULT_PRECIS;
  fontStruct.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  fontStruct.lfQuality = DEFAULT_QUALITY;
  fontStruct.lfPitchAndFamily = DEFAULT_PITCH | family;
  strcpy(fontStruct.lfFaceName, fontname);

  HFONT hFont = CreateFontIndirect(&fontStruct);
  HFONT hOldFont = (HFONT) SelectObject(hdc, hFont);

  // Set the compositing operator
  int compositeMode = this->GetCompositingMode(actor);
  SetROP2(hdc, compositeMode);
  // For Debug
  int op = GetROP2(hdc);
  if (op != compositeMode)
    {
    vtkErrorMacro(<<"vtkWin32TextMapper::Render - ROP not set!");
    }

  // Define bounding rectangle
  RECT rect;
  rect.left = ptDestOff.x;
  rect.top = ptDestOff.y;
  rect.bottom = ptDestOff.y;
  rect.right = ptDestOff.x;

  // Calculate the size of the bounding rectangle
  DrawText(hdc, this->Input, strlen(this->Input), &rect,
	   DT_CALCRECT|DT_LEFT|DT_NOPREFIX);

  // Set the colors for the shadow
  long status;
  if (this->Shadow)
    {
    status = SetTextColor(hdc, RGB(shadowRed, shadowGreen, shadowBlue));
    if (status == CLR_INVALID)
      vtkErrorMacro(<<"vtkWin32TextMapper::Render - Set shadow color failed!");

    // Set the background mode to transparent
    SetBkMode(hdc, TRANSPARENT);

    // Draw the shadow text
    rect.left++;  rect.top++; rect.bottom++; rect.right++;
    DrawText(hdc, this->Input, strlen(this->Input), &rect,DT_LEFT|DT_NOPREFIX);
    rect.left--;  rect.top--; rect.bottom--; rect.right--;
    }

  // set the colors for the foreground
  status = SetTextColor(hdc, RGB(red, green, blue));
  if (status == CLR_INVALID)
    vtkErrorMacro(<<"vtkWin32TextMapper::Render - SetTextColor failed!");

  // Set the background mode to transparent
  SetBkMode(hdc, TRANSPARENT);

  // Draw the text
  DrawText(hdc, this->Input, strlen(this->Input), &rect, DT_LEFT|DT_NOPREFIX);

  SelectObject(hdc, hOldFont);
  DeleteObject(hFont);

}

<commit_msg>BUG: fixed positioning of text<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWin32TextMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to Matt Turek who developed this class.

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkWin32TextMapper.h"
#include "vtkWin32ImageWindow.h"

int vtkWin32TextMapper::GetCompositingMode(vtkActor2D* actor)
{
  vtkProperty2D* tempProp = actor->GetProperty();
  int compositeMode = tempProp->GetCompositingOperator();

  switch (compositeMode)
  {
  case VTK_BLACK:
	  return R2_BLACK;
	  break;
  case VTK_NOT_DEST:
	  return R2_NOT;
	  break;
  case VTK_SRC_AND_DEST:
	  return R2_MASKPEN;
	  break;
  case VTK_SRC_OR_DEST:
	  return  R2_MERGEPEN;
	  break;
  case VTK_NOT_SRC:
	  return R2_NOTCOPYPEN;
	  break;
  case VTK_SRC_XOR_DEST:
	  return R2_XORPEN;
      break;
  case VTK_SRC_AND_notDEST:
	  return R2_MASKPENNOT;
	  break;
  case VTK_SRC:
	  return R2_COPYPEN;
	  break;
  case VTK_WHITE:
	  return R2_WHITE;
	  break;
  default:
	  return R2_COPYPEN;
	  break;
  }

}

void vtkWin32TextMapper::Render(vtkViewport* viewport, vtkActor2D* actor)
{

  vtkDebugMacro (<< "vtkWin32TextMapper::Render");

  // Check for input
  if (this->Input == NULL)
    {
    vtkErrorMacro (<<"vtkWin32TextMapper::Render - No input");
    }

  // Get the window information for display
  vtkWindow*  window = viewport->GetVTKWindow();
  HWND windowId = (HWND) window->GetGenericWindowId();

  // Get the device context from the window

  HDC hdc = (HDC) window->GetGenericContext();

  // Get the position of the text actor
  POINT ptDestOff;
  int xOffset = 0;
  int yOffset = 0;

  // Get the position of the text actor
  int* actorPos =
    actor->GetPositionCoordinate()->GetComputedLocalDisplayValue(viewport);
  xOffset = actorPos[0];
  yOffset = actorPos[1];

  ptDestOff.x = xOffset;
  ptDestOff.y = yOffset;

  // Set up the font color from the text actor
  unsigned char red = 0;
  unsigned char green = 0;
  unsigned char blue = 0;
  float*  actorColor = actor->GetProperty()->GetColor();
  red = (unsigned char) (actorColor[0] * 255.0);
  green = (unsigned char) (actorColor[1] * 255.0);
  blue = (unsigned char) (actorColor[2] * 255.0);

  // Set up the shadow color
  float intensity;
  intensity = (red + green + blue)/3.0;

  unsigned char shadowRed, shadowGreen, shadowBlue;
  if (intensity > 128)
    {
    shadowRed = shadowBlue = shadowGreen = 0;
    }
  else
    {
    shadowRed = shadowBlue = shadowGreen = 255;
    }

  // Create the font
  LOGFONT fontStruct;
  char fontname[32];
  DWORD family;
  switch (this->FontFamily)
    {
    case VTK_ARIAL:
      strcpy(fontname, "Arial");
	  family = FF_SWISS;
	  break;
	case VTK_TIMES:
      strcpy(fontname, "Times Roman");
	  family = FF_ROMAN;
	  break;
	case VTK_COURIER:
      strcpy(fontname, "Courier");
	  family = FF_MODERN;
	  break;
	default:
      strcpy(fontname, "Arial");
	  family = FF_SWISS;
	  break;
    }

  fontStruct.lfHeight = MulDiv(this->FontSize,
			       GetDeviceCaps(hdc, LOGPIXELSY), 72);
  // height in logical units
  fontStruct.lfWidth = 0;  // default width
  fontStruct.lfEscapement = 0;
  fontStruct.lfOrientation = 0;
  if (this->Bold == 1)
    {
    fontStruct.lfWeight = FW_BOLD;
    }
  else
    {
    fontStruct.lfWeight = FW_NORMAL;
    }
  fontStruct.lfItalic = this->Italic;
  fontStruct.lfUnderline = 0;
  fontStruct.lfStrikeOut = 0;
  fontStruct.lfCharSet = ANSI_CHARSET;
  fontStruct.lfOutPrecision = OUT_DEFAULT_PRECIS;
  fontStruct.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  fontStruct.lfQuality = DEFAULT_QUALITY;
  fontStruct.lfPitchAndFamily = DEFAULT_PITCH | family;
  strcpy(fontStruct.lfFaceName, fontname);

  HFONT hFont = CreateFontIndirect(&fontStruct);
  HFONT hOldFont = (HFONT) SelectObject(hdc, hFont);

  // Set the compositing operator
  int compositeMode = this->GetCompositingMode(actor);
  SetROP2(hdc, compositeMode);
  // For Debug
  int op = GetROP2(hdc);
  if (op != compositeMode)
    {
    vtkErrorMacro(<<"vtkWin32TextMapper::Render - ROP not set!");
    }

  // Define bounding rectangle
  RECT rect;
  rect.left = ptDestOff.x;
  rect.top = ptDestOff.y;
  rect.bottom = ptDestOff.y;
  rect.right = ptDestOff.x;

  // Calculate the size of the bounding rectangle
  DrawText(hdc, this->Input, strlen(this->Input), &rect,
	   DT_CALCRECT|DT_LEFT|DT_NOPREFIX);

  // adjust the rectangle to account for lower left origin
  rect.top = 2*rect.top - rect.bottom;
  rect.bottom = ptDestOff.y;

  // Set the colors for the shadow
  long status;
  if (this->Shadow)
    {
    status = SetTextColor(hdc, RGB(shadowRed, shadowGreen, shadowBlue));
    if (status == CLR_INVALID)
      vtkErrorMacro(<<"vtkWin32TextMapper::Render - Set shadow color failed!");

    // Set the background mode to transparent
    SetBkMode(hdc, TRANSPARENT);

    // Draw the shadow text
    rect.left++;  rect.top++; rect.bottom++; rect.right++;
    DrawText(hdc, this->Input, strlen(this->Input), &rect,DT_LEFT|DT_NOPREFIX);
    rect.left--;  rect.top--; rect.bottom--; rect.right--;
    }

  // set the colors for the foreground
  status = SetTextColor(hdc, RGB(red, green, blue));
  if (status == CLR_INVALID)
    vtkErrorMacro(<<"vtkWin32TextMapper::Render - SetTextColor failed!");

  // Set the background mode to transparent
  SetBkMode(hdc, TRANSPARENT);

  // Draw the text
  DrawText(hdc, this->Input, strlen(this->Input), &rect, DT_LEFT|DT_NOPREFIX);

  SelectObject(hdc, hOldFont);
  DeleteObject(hFont);

}

<|endoftext|>


<commit_before>// -*-c++-*-

/*
 * demonstrates usage of osg::TextureRectangle.
 *
 * Actually there isn't much difference to the rest of the osg::Texture*
 * bunch only this:
 * - texture coordinates for texture rectangles must be in image
 *   coordinates instead of normalized coordinates (0-1). So for a 500x250
 *   image the coordinates for the entire image would be
 *   0,250 0,0 500,0 500,250 instead of 0,1 0,0 1,0 1,1
 * - only the following wrap modes are supported (but not enforced)
 *   CLAMP, CLAMP_TO_EDGE, CLAMP_TO_BORDER
 * - a border is not supported
 * - mipmap is not supported
 */

#include <osg/Notify>
#include <osg/TextureRectangle>
#include <osg/Geometry>
#include <osg/Geode>

#include <osg/Group>
#include <osg/Projection>
#include <osg/MatrixTransform>
#include <osgText/Text>

#include <osgDB/Registry>
#include <osgDB/ReadFile>

#include <osgProducer/Viewer>

/**********************************************************************
 *
 * Texture pan animation callback
 *
 **********************************************************************/

class TexturePanCallback : public osg::NodeCallback
{
public:
    TexturePanCallback(osg::Geometry* geom, osg::Image* img,
                       double delay = 0.05) :
        _geom(geom),
        _img(img),
        _phaseS(35.0f),
        _phaseT(18.0f),
        _phaseScale(5.0f),
        _delay(delay),
        _prevTime(0.0)
    {
    }

    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
    {
        if (!_geom || !_img)
            return;

        if (nv->getFrameStamp()) {
            double currTime = nv->getFrameStamp()->getReferenceTime();
            if (currTime - _prevTime > _delay) {

                float rad = osg::DegreesToRadians(currTime);

                // zoom scale (0.2 - 1.0)
                float scale = sin(rad * _phaseScale) * 0.4f + 0.6f;
                float scaleR = 1.0f - scale;

                // calculate new texture coordinates
                float s, t;
                s = ((sin(rad * _phaseS) + 1) * 0.5f) * (_img->s() * scaleR);
                t = ((sin(rad * _phaseT) + 1) * 0.5f) * (_img->t() * scaleR);

                // set new texture coordinate array
                osg::Vec2Array* texcoords = (osg::Vec2Array*) _geom->getTexCoordArray(0);
                float w = _img->s() * scale, h = _img->t() * scale;
                (*texcoords)[0].set(s, t+h);
                (*texcoords)[1].set(s, t);
                (*texcoords)[2].set(s+w, t);
                (*texcoords)[3].set(s+w, t+h);

                // record time
                _prevTime = currTime;
            }
        }
    }

private:
    osg::Geometry* _geom;
    osg::Image* _img;

    float _phaseS, _phaseT, _phaseScale;

    double _delay;
    double _prevTime;
};

osg::Node* createRectangle(osg::BoundingBox& bb,
                           const std::string& filename)
{
    osg::Vec3 top_left(bb.xMin(),bb.yMax(),bb.zMax());
    osg::Vec3 bottom_left(bb.xMin(),bb.yMax(),bb.zMin());
    osg::Vec3 bottom_right(bb.xMax(),bb.yMax(),bb.zMin());
    osg::Vec3 top_right(bb.xMax(),bb.yMax(),bb.zMax());

    // create geometry
    osg::Geometry* geom = new osg::Geometry;

    osg::Vec3Array* vertices = new osg::Vec3Array(4);
    (*vertices)[0] = top_left;
    (*vertices)[1] = bottom_left;
    (*vertices)[2] = bottom_right;
    (*vertices)[3] = top_right;
    geom->setVertexArray(vertices);

    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
    (*texcoords)[0].set(0.0f, 0.0f);
    (*texcoords)[1].set(1.0f, 0.0f);
    (*texcoords)[2].set(1.0f, 1.0f);
    (*texcoords)[3].set(0.0f, 1.0f);
    geom->setTexCoordArray(0,texcoords);

    osg::Vec3Array* normals = new osg::Vec3Array(1);
    (*normals)[0].set(-1.0f,0.0f,0.0f);
    geom->setNormalArray(normals);
    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

    osg::Vec4Array* colors = new osg::Vec4Array(1);
    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
    geom->setColorArray(colors);
    geom->setColorBinding(osg::Geometry::BIND_OVERALL);

    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));

    // disable display list so our modified tex coordinates show up
    geom->setUseDisplayList(false);

    // setup texture
    osg::TextureRectangle* texture = new osg::TextureRectangle;

    // load image
    osg::Image* img = osgDB::readImageFile(filename);
    texture->setImage(img);

    // setup state
    osg::StateSet* state = geom->getOrCreateStateSet();
    state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);

    // turn off lighting
    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

    // install 'update' callback
    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(geom);
    geode->setUpdateCallback(new TexturePanCallback(geom, img));

    return geode;
}

osg::Geode* createText(const std::string& str,
                       const osg::Vec3& pos)
{
    static std::string font("fonts/arial.ttf");

    osg::Geode* geode = new osg::Geode;

    osgText::Text* text = new osgText::Text;
    geode->addDrawable(text);

    text->setFont(font);
    text->setPosition(pos);
    text->setText(str);

    return geode;
}

osg::Node* createHUD()
{
    osg::Group* group = new osg::Group;

    // turn off lighting and depth test
    osg::StateSet* state = group->getOrCreateStateSet();
    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    state->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);

    // add text
    osg::Vec3 pos(120.0f, 800.0f, 0.0f);
    const osg::Vec3 delta(0.0f, -80.0f, 0.0f);

    const char* text[] = {
        "TextureRectangle Mini-HOWTO",
        "- essentially behaves like Texture2D, *except* that:",
        "- tex coords must be non-normalized (0..pixel) instead of (0..1)",
        "- wrap modes must be CLAMP, CLAMP_TO_EDGE, or CLAMP_TO_BORDER\n  repeating wrap modes are not supported",
        "- filter modes must be NEAREST or LINEAR since\n  mipmaps are not supported",
        "- texture borders are not supported",
        "- defaults should be fine",
        NULL
    };
    const char** t = text;
    while (*t) {
        group->addChild(createText(*t++, pos));
        pos += delta;
    }

    // create HUD
    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
    modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE);
    modelview_abs->setMatrix(osg::Matrix::identity());
    modelview_abs->addChild(group);

    osg::Projection* projection = new osg::Projection;
    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
    projection->addChild(modelview_abs);

    return projection;
}

osg::Node* createModel(const std::string& filename)
{
    osg::Group* root = new osg::Group;

    if (filename != "X") {
        osg::BoundingBox bb(0.0f,0.0f,0.0f,1.0f,1.0f,1.0f);
        root->addChild(createRectangle(bb, filename)); // XXX
    }

    root->addChild(createHUD());

    return root;
}

int main(int argc, char** argv)
{
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is a demo which demonstrates use of osg::TextureRectangle.");
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] <image> ...");
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");

    // construct the viewer.
    osgProducer::Viewer viewer(arguments);

    // set up the value with sensible default event handlers.
    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);

    // get details on keyboard and mouse bindings used by the viewer.
    viewer.getUsage(*arguments.getApplicationUsage());

    // if user request help write it out to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        arguments.getApplicationUsage()->write(std::cout);
        return 1;
    }

    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occured when parsing the program aguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }

    // create a model from the images.
    osg::Node* rootNode = createModel((arguments.argc() > 1 ? arguments[1] : "lz.rgb"));

    // add model to viewer.
    viewer.setSceneData(rootNode);

    // create the windows and run the threads.
    viewer.realize();

    while (!viewer.done())
    {
        // wait for all cull and draw threads to complete.
        viewer.sync();

        // update the scene by traversing it with the the update visitor which will
        // call all node update callbacks and animations.
        viewer.update();

        // fire off the cull and draw traversals of the scene.
        viewer.frame();
    }

    // wait for all cull and draw threads to complete before exit.
    viewer.sync();

    return 0;
}
<commit_msg>Added Images/ infront of lz.rgb path.<commit_after>// -*-c++-*-

/*
 * demonstrates usage of osg::TextureRectangle.
 *
 * Actually there isn't much difference to the rest of the osg::Texture*
 * bunch only this:
 * - texture coordinates for texture rectangles must be in image
 *   coordinates instead of normalized coordinates (0-1). So for a 500x250
 *   image the coordinates for the entire image would be
 *   0,250 0,0 500,0 500,250 instead of 0,1 0,0 1,0 1,1
 * - only the following wrap modes are supported (but not enforced)
 *   CLAMP, CLAMP_TO_EDGE, CLAMP_TO_BORDER
 * - a border is not supported
 * - mipmap is not supported
 */

#include <osg/Notify>
#include <osg/TextureRectangle>
#include <osg/Geometry>
#include <osg/Geode>

#include <osg/Group>
#include <osg/Projection>
#include <osg/MatrixTransform>
#include <osgText/Text>

#include <osgDB/Registry>
#include <osgDB/ReadFile>

#include <osgProducer/Viewer>

/**********************************************************************
 *
 * Texture pan animation callback
 *
 **********************************************************************/

class TexturePanCallback : public osg::NodeCallback
{
public:
    TexturePanCallback(osg::Geometry* geom, osg::Image* img,
                       double delay = 0.05) :
        _geom(geom),
        _img(img),
        _phaseS(35.0f),
        _phaseT(18.0f),
        _phaseScale(5.0f),
        _delay(delay),
        _prevTime(0.0)
    {
    }

    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
    {
        if (!_geom || !_img)
            return;

        if (nv->getFrameStamp()) {
            double currTime = nv->getFrameStamp()->getReferenceTime();
            if (currTime - _prevTime > _delay) {

                float rad = osg::DegreesToRadians(currTime);

                // zoom scale (0.2 - 1.0)
                float scale = sin(rad * _phaseScale) * 0.4f + 0.6f;
                float scaleR = 1.0f - scale;

                // calculate new texture coordinates
                float s, t;
                s = ((sin(rad * _phaseS) + 1) * 0.5f) * (_img->s() * scaleR);
                t = ((sin(rad * _phaseT) + 1) * 0.5f) * (_img->t() * scaleR);

                // set new texture coordinate array
                osg::Vec2Array* texcoords = (osg::Vec2Array*) _geom->getTexCoordArray(0);
                float w = _img->s() * scale, h = _img->t() * scale;
                (*texcoords)[0].set(s, t+h);
                (*texcoords)[1].set(s, t);
                (*texcoords)[2].set(s+w, t);
                (*texcoords)[3].set(s+w, t+h);

                // record time
                _prevTime = currTime;
            }
        }
    }

private:
    osg::Geometry* _geom;
    osg::Image* _img;

    float _phaseS, _phaseT, _phaseScale;

    double _delay;
    double _prevTime;
};

osg::Node* createRectangle(osg::BoundingBox& bb,
                           const std::string& filename)
{
    osg::Vec3 top_left(bb.xMin(),bb.yMax(),bb.zMax());
    osg::Vec3 bottom_left(bb.xMin(),bb.yMax(),bb.zMin());
    osg::Vec3 bottom_right(bb.xMax(),bb.yMax(),bb.zMin());
    osg::Vec3 top_right(bb.xMax(),bb.yMax(),bb.zMax());

    // create geometry
    osg::Geometry* geom = new osg::Geometry;

    osg::Vec3Array* vertices = new osg::Vec3Array(4);
    (*vertices)[0] = top_left;
    (*vertices)[1] = bottom_left;
    (*vertices)[2] = bottom_right;
    (*vertices)[3] = top_right;
    geom->setVertexArray(vertices);

    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
    (*texcoords)[0].set(0.0f, 0.0f);
    (*texcoords)[1].set(1.0f, 0.0f);
    (*texcoords)[2].set(1.0f, 1.0f);
    (*texcoords)[3].set(0.0f, 1.0f);
    geom->setTexCoordArray(0,texcoords);

    osg::Vec3Array* normals = new osg::Vec3Array(1);
    (*normals)[0].set(-1.0f,0.0f,0.0f);
    geom->setNormalArray(normals);
    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

    osg::Vec4Array* colors = new osg::Vec4Array(1);
    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
    geom->setColorArray(colors);
    geom->setColorBinding(osg::Geometry::BIND_OVERALL);

    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));

    // disable display list so our modified tex coordinates show up
    geom->setUseDisplayList(false);

    // setup texture
    osg::TextureRectangle* texture = new osg::TextureRectangle;

    // load image
    osg::Image* img = osgDB::readImageFile(filename);
    texture->setImage(img);

    // setup state
    osg::StateSet* state = geom->getOrCreateStateSet();
    state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);

    // turn off lighting
    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

    // install 'update' callback
    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(geom);
    geode->setUpdateCallback(new TexturePanCallback(geom, img));

    return geode;
}

osg::Geode* createText(const std::string& str,
                       const osg::Vec3& pos)
{
    static std::string font("fonts/arial.ttf");

    osg::Geode* geode = new osg::Geode;

    osgText::Text* text = new osgText::Text;
    geode->addDrawable(text);

    text->setFont(font);
    text->setPosition(pos);
    text->setText(str);

    return geode;
}

osg::Node* createHUD()
{
    osg::Group* group = new osg::Group;

    // turn off lighting and depth test
    osg::StateSet* state = group->getOrCreateStateSet();
    state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    state->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);

    // add text
    osg::Vec3 pos(120.0f, 800.0f, 0.0f);
    const osg::Vec3 delta(0.0f, -80.0f, 0.0f);

    const char* text[] = {
        "TextureRectangle Mini-HOWTO",
        "- essentially behaves like Texture2D, *except* that:",
        "- tex coords must be non-normalized (0..pixel) instead of (0..1)",
        "- wrap modes must be CLAMP, CLAMP_TO_EDGE, or CLAMP_TO_BORDER\n  repeating wrap modes are not supported",
        "- filter modes must be NEAREST or LINEAR since\n  mipmaps are not supported",
        "- texture borders are not supported",
        "- defaults should be fine",
        NULL
    };
    const char** t = text;
    while (*t) {
        group->addChild(createText(*t++, pos));
        pos += delta;
    }

    // create HUD
    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
    modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE);
    modelview_abs->setMatrix(osg::Matrix::identity());
    modelview_abs->addChild(group);

    osg::Projection* projection = new osg::Projection;
    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
    projection->addChild(modelview_abs);

    return projection;
}

osg::Node* createModel(const std::string& filename)
{
    osg::Group* root = new osg::Group;

    if (filename != "X") {
        osg::BoundingBox bb(0.0f,0.0f,0.0f,1.0f,1.0f,1.0f);
        root->addChild(createRectangle(bb, filename)); // XXX
    }

    root->addChild(createHUD());

    return root;
}

int main(int argc, char** argv)
{
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is a demo which demonstrates use of osg::TextureRectangle.");
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] <image> ...");
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");

    // construct the viewer.
    osgProducer::Viewer viewer(arguments);

    // set up the value with sensible default event handlers.
    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);

    // get details on keyboard and mouse bindings used by the viewer.
    viewer.getUsage(*arguments.getApplicationUsage());

    // if user request help write it out to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        arguments.getApplicationUsage()->write(std::cout);
        return 1;
    }

    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occured when parsing the program aguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }

    // create a model from the images.
    osg::Node* rootNode = createModel((arguments.argc() > 1 ? arguments[1] : "Images/lz.rgb"));

    // add model to viewer.
    viewer.setSceneData(rootNode);

    // create the windows and run the threads.
    viewer.realize();

    while (!viewer.done())
    {
        // wait for all cull and draw threads to complete.
        viewer.sync();

        // update the scene by traversing it with the the update visitor which will
        // call all node update callbacks and animations.
        viewer.update();

        // fire off the cull and draw traversals of the scene.
        viewer.frame();
    }

    // wait for all cull and draw threads to complete before exit.
    viewer.sync();

    return 0;
}
<|endoftext|>


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

#include <gi_parse.hxx>

#include <stdio.h>
#include <string.h>
#include <fstream>
#include <gilacces.hxx>

using namespace std;

const char * C_sLineEnd = "\r\n";

inline void
WriteStr( ostream & o_rOut, const Simstr & i_rStr )
{
    o_rOut.write( i_rStr.str(), i_rStr.l() );
}

inline void
WriteStr( ostream & o_rOut, const char * i_rStr )
{
    o_rOut.write( i_rStr, strlen(i_rStr) );
}

inline void
GenericInfo_Parser::SetError( E_Error i_eError )
{
     eErrorCode = i_eError;
    nErrorLine = nCurLine;
}

GenericInfo_Parser::GenericInfo_Parser()
    :   sCurParsePosition(""),
        nCurLine(0),
        nLevel(0),
        bGoon(false),
        // sCurComment,
        eErrorCode(ok),
        nErrorLine(0),
        pResult(0),
        pResource(0)
{
}

GenericInfo_Parser::~GenericInfo_Parser()
{
}

bool
GenericInfo_Parser::LoadList( GenericInfoList_Builder &  o_rResult,
                              const Simstr &             i_sSourceFileName )
{
    ifstream  aFile( i_sSourceFileName.str() );
    if ( aFile.fail() )
    {
        SetError(cannot_open);
        return false;
    }

    ResetState(o_rResult);

    for ( ReadLine(aFile); bGoon; ReadLine(aFile) )
    {
        bool bOk = InterpretLine();
        if ( !bOk)
        {
            SetError(syntax_error);
            break;
        }
    }

    if ( nLevel > 0 && eErrorCode == ok)
    {
        SetError(unexpected_eof);
    }
    else if ( nLevel < 0 )
    {
        SetError(unexpected_list_end);
    }

    aFile.close();
    return eErrorCode == ok;
}

bool
GenericInfo_Parser::SaveList( const Simstr &            i_rOutputFile,
                              GenericInfoList_Browser & io_rListBrowser )
{
    ofstream  aFile( i_rOutputFile.str() );
    if ( aFile.fail() )
    {
        SetError(cannot_open);
        return false;
    }

    ResetState(io_rListBrowser);

    WriteList(aFile);

    aFile.close();
    return eErrorCode == ok;
}

void
GenericInfo_Parser::ResetState( GenericInfoList_Builder & io_rResult )
{
    sCurParsePosition = "";
    nCurLine = 0;
    nLevel = 0;
    bGoon = true;
    sCurComment = "";
    eErrorCode = ok;
    nErrorLine = 0;
    pResult = &io_rResult;
    pResource = 0;
}

void
GenericInfo_Parser::ResetState( GenericInfoList_Browser & io_rSrc )
{
    sCurParsePosition = "";
    nCurLine = 0;
    nLevel = 0;
    bGoon = false;
    sCurComment = "";
    eErrorCode = ok;
    nErrorLine = 0;
    pResult = 0;
    pResource = &io_rSrc;
}

void
GenericInfo_Parser::ReadLine( istream & i_rSrc )
{
    const int nInputSize = 32000;
    static char sInput[nInputSize];

    i_rSrc.get(sInput, nInputSize);
    UINT32 nGot = UINT32(i_rSrc.gcount());
    if (nGot == 0)
    {
        bGoon = false;
        return;
    }

    nCurLine++;

#if 0
    if ( sInput[ nGot-1 ] == '\r' )
        sInput[ nGot-1 ] = '\0';
#endif
    i_rSrc.get();

    for ( sCurParsePosition = &sInput[0]; *sCurParsePosition > 0 && *sCurParsePosition <= 32; ++sCurParsePosition );
    for ( char * sEnd = const_cast< char* >(strchr(sCurParsePosition,'\0'));
          sEnd != sCurParsePosition
                ? *(sEnd-1) <= 32
                : false;
          --sEnd )
    {
        *(sEnd-1) = '\0';
    }
}

bool
GenericInfo_Parser::InterpretLine()
{
    switch ( ClassifyLine() )
    {
        case lt_key:        ReadKey();
                            break;
        case lt_open_list:  PushLevel_Read();
                            break;
        case lt_close_list: PopLevel_Read();
                            break;
        case lt_comment:    AddCurLine2CurComment();
                            break;
        case lt_empty:      AddCurLine2CurComment();
                            break;
        default:
                            return false;
    }
    return true;
}

GenericInfo_Parser::E_LineType
GenericInfo_Parser::ClassifyLine()
{
    switch ( *sCurParsePosition )
    {
         case '{':   return lt_open_list;
        case '}':   return lt_close_list;
        case '#':   return lt_comment;
        case '0':   return lt_empty;
    }

    return lt_key;
}

void
GenericInfo_Parser::ReadKey()
{
    const char * pSearch = sCurParsePosition;

    for ( ; *pSearch > 32; ++pSearch );
    UINT32 nKeyLength = pSearch - sCurParsePosition;

    for ( ; *pSearch <= 32 && *pSearch > '\0'; ++pSearch );

    pResult->AddKey( sCurParsePosition,     nKeyLength,
                     pSearch,               strlen(pSearch),
                     sCurComment.str(),     sCurComment.l()
                   );
}

void
GenericInfo_Parser::PushLevel_Read()
{
    nLevel++;
    pResult->OpenList();
}

void
GenericInfo_Parser::PopLevel_Read()
{
    nLevel--;
    pResult->CloseList();
}

void
GenericInfo_Parser::AddCurLine2CurComment()
{
    sCurComment +=  sCurParsePosition;
    sCurComment +=  C_sLineEnd;
}

void
GenericInfo_Parser::WriteList( ostream & o_rFile )
{
    static char sBuffer[32000];

    for ( bGoon = pResource->Start_CurList();
          bGoon;
          bGoon = pResource->NextOf_CurList() )
    {
        pResource->Get_CurComment(&sBuffer[0]);
        WriteComment(o_rFile,sBuffer);

        pResource->Get_CurKey(&sBuffer[0]);
        WriteKey(o_rFile,sBuffer);

        pResource->Get_CurValue(&sBuffer[0]);
        WriteValue(o_rFile,sBuffer);

        if ( pResource->HasSubList_CurKey() )
        {
            PushLevel_Write();

/*
            WriteIndentation();
            o_rFile.write("{",1);
            o_rFile.write(C_sLineEnd, C_nLineEndLength);
*/
            WriteList(o_rFile);

/*
            WriteIndentation();
            o_rFile.write("}",1);
            o_rFile.write(C_sLineEnd, C_nLineEndLength);
*/
            PopLevel_Write();
        }
    }   // end for
}

void
GenericInfo_Parser::PushLevel_Write()
{
    nLevel++;
    pResource->Push_CurList();
}

void
GenericInfo_Parser::PopLevel_Write()
{
    nLevel--;
    pResource->Pop_CurList();
}

void
GenericInfo_Parser::WriteComment( ostream &    o_rFile,
                                  const char *  i_sStr )
{
    WriteStr( o_rFile, i_sStr );
    if ( i_sStr[ strlen(i_sStr)-1 ] != '\n' )
        WriteStr( o_rFile, C_sLineEnd );
}

void
GenericInfo_Parser::WriteKey( ostream &    o_rFile,
                              const char *  i_sStr )
{
    WriteIndentation(o_rFile);
    WriteStr( o_rFile, i_sStr );
}

void
GenericInfo_Parser::WriteValue( ostream &    o_rFile,
                                const char *  i_sStr )
{
    if ( i_sStr != 0 ? strlen(i_sStr) > 0 : false )
    {
         WriteStr(o_rFile," ");
         WriteStr(o_rFile,i_sStr);
    }

    WriteStr(o_rFile,C_sLineEnd);
}

void
GenericInfo_Parser::WriteIndentation( ostream &    o_rFile )
{
    const int nIndentBound = 60;

    static const char sIndentation[nIndentBound+1] =
        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";

    if ( nLevel == 0 )
        return;

    if ( nLevel <= nIndentBound )
        o_rFile.write( sIndentation, nLevel );
    else
    {
        INT16 iLevel = nLevel;
        for ( ; iLevel > nIndentBound; iLevel-=nIndentBound )
            o_rFile.write( sIndentation, nIndentBound );
        o_rFile.write( sIndentation, iLevel );
    }
}

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

#include <gi_parse.hxx>

#include <stdio.h>
#include <string.h>
#include <fstream>
#include <gilacces.hxx>

using namespace std;

const char * C_sLineEnd = "\r\n";

inline void
WriteStr( ostream & o_rOut, const Simstr & i_rStr )
{
    o_rOut.write( i_rStr.str(), i_rStr.l() );
}

inline void
WriteStr( ostream & o_rOut, const char * i_rStr )
{
    o_rOut.write( i_rStr, strlen(i_rStr) );
}

inline void
GenericInfo_Parser::SetError( E_Error i_eError )
{
     eErrorCode = i_eError;
    nErrorLine = nCurLine;
}

GenericInfo_Parser::GenericInfo_Parser()
    :   sCurParsePosition(""),
        nCurLine(0),
        nLevel(0),
        bGoon(false),
        // sCurComment,
        eErrorCode(ok),
        nErrorLine(0),
        pResult(0),
        pResource(0)
{
}

GenericInfo_Parser::~GenericInfo_Parser()
{
}

bool
GenericInfo_Parser::LoadList( GenericInfoList_Builder &  o_rResult,
                              const Simstr &             i_sSourceFileName )
{
    ifstream  aFile( i_sSourceFileName.str() );
    if ( aFile.fail() )
    {
        SetError(cannot_open);
        return false;
    }

    ResetState(o_rResult);

    for ( ReadLine(aFile); bGoon; ReadLine(aFile) )
    {
        bool bOk = InterpretLine();
        if ( !bOk)
        {
            SetError(syntax_error);
            break;
        }
    }

    if ( nLevel > 0 && eErrorCode == ok)
    {
        SetError(unexpected_eof);
    }
    else if ( nLevel < 0 )
    {
        SetError(unexpected_list_end);
    }

    aFile.close();
    return eErrorCode == ok;
}

bool
GenericInfo_Parser::SaveList( const Simstr &            i_rOutputFile,
                              GenericInfoList_Browser & io_rListBrowser )
{
    ofstream  aFile( i_rOutputFile.str() );
    if ( aFile.fail() )
    {
        SetError(cannot_open);
        return false;
    }

    ResetState(io_rListBrowser);

    WriteList(aFile);

    aFile.close();
    return eErrorCode == ok;
}

void
GenericInfo_Parser::ResetState( GenericInfoList_Builder & io_rResult )
{
    sCurParsePosition = "";
    nCurLine = 0;
    nLevel = 0;
    bGoon = true;
    sCurComment = "";
    eErrorCode = ok;
    nErrorLine = 0;
    pResult = &io_rResult;
    pResource = 0;
}

void
GenericInfo_Parser::ResetState( GenericInfoList_Browser & io_rSrc )
{
    sCurParsePosition = "";
    nCurLine = 0;
    nLevel = 0;
    bGoon = false;
    sCurComment = "";
    eErrorCode = ok;
    nErrorLine = 0;
    pResult = 0;
    pResource = &io_rSrc;
}

void
GenericInfo_Parser::ReadLine( istream & i_rSrc )
{
    const int nInputSize = 32000;
    static char sInput[nInputSize];

    i_rSrc.get(sInput, nInputSize);
    UINT32 nGot = UINT32(i_rSrc.gcount());
    if (nGot == 0 && i_rSrc.eof())
    {
        bGoon = false;
        return;
    }

    nCurLine++;

#if 0
    if ( sInput[ nGot-1 ] == '\r' )
        sInput[ nGot-1 ] = '\0';
#endif
    i_rSrc.get();

    for ( sCurParsePosition = &sInput[0]; *sCurParsePosition > 0 && *sCurParsePosition <= 32; ++sCurParsePosition );
    for ( char * sEnd = const_cast< char* >(strchr(sCurParsePosition,'\0'));
          sEnd != sCurParsePosition
                ? *(sEnd-1) <= 32
                : false;
          --sEnd )
    {
        *(sEnd-1) = '\0';
    }
}

bool
GenericInfo_Parser::InterpretLine()
{
    switch ( ClassifyLine() )
    {
        case lt_key:        ReadKey();
                            break;
        case lt_open_list:  PushLevel_Read();
                            break;
        case lt_close_list: PopLevel_Read();
                            break;
        case lt_comment:    AddCurLine2CurComment();
                            break;
        case lt_empty:      AddCurLine2CurComment();
                            break;
        default:
                            return false;
    }
    return true;
}

GenericInfo_Parser::E_LineType
GenericInfo_Parser::ClassifyLine()
{
    switch ( *sCurParsePosition )
    {
         case '{':   return lt_open_list;
        case '}':   return lt_close_list;
        case '#':   return lt_comment;
        case '\0':   return lt_empty;
    }

    return lt_key;
}

void
GenericInfo_Parser::ReadKey()
{
    const char * pSearch = sCurParsePosition;

    for ( ; *pSearch > 32; ++pSearch );
    UINT32 nKeyLength = pSearch - sCurParsePosition;

    for ( ; *pSearch <= 32 && *pSearch > '\0'; ++pSearch );

    pResult->AddKey( sCurParsePosition,     nKeyLength,
                     pSearch,               strlen(pSearch),
                     sCurComment.str(),     sCurComment.l()
                   );
    sCurComment = "";
}

void
GenericInfo_Parser::PushLevel_Read()
{
    nLevel++;
    pResult->OpenList();
}

void
GenericInfo_Parser::PopLevel_Read()
{
    nLevel--;
    pResult->CloseList();
}

void
GenericInfo_Parser::AddCurLine2CurComment()
{
    sCurComment +=  sCurParsePosition;
    sCurComment +=  C_sLineEnd;
}

void
GenericInfo_Parser::WriteList( ostream & o_rFile )
{
    static char sBuffer[32000];

    for ( bGoon = pResource->Start_CurList();
          bGoon;
          bGoon = pResource->NextOf_CurList() )
    {
        pResource->Get_CurComment(&sBuffer[0]);
        WriteComment(o_rFile,sBuffer);

        pResource->Get_CurKey(&sBuffer[0]);
        WriteKey(o_rFile,sBuffer);

        pResource->Get_CurValue(&sBuffer[0]);
        WriteValue(o_rFile,sBuffer);

        if ( pResource->HasSubList_CurKey() )
        {
            PushLevel_Write();

/*
            WriteIndentation();
            o_rFile.write("{",1);
            o_rFile.write(C_sLineEnd, C_nLineEndLength);
*/
            WriteList(o_rFile);

/*
            WriteIndentation();
            o_rFile.write("}",1);
            o_rFile.write(C_sLineEnd, C_nLineEndLength);
*/
            PopLevel_Write();
        }
    }   // end for
}

void
GenericInfo_Parser::PushLevel_Write()
{
    nLevel++;
    pResource->Push_CurList();
}

void
GenericInfo_Parser::PopLevel_Write()
{
    nLevel--;
    pResource->Pop_CurList();
}

void
GenericInfo_Parser::WriteComment( ostream &    o_rFile,
                                  const char *  i_sStr )
{
    WriteStr( o_rFile, i_sStr );
    if ( i_sStr[ strlen(i_sStr)-1 ] != '\n' )
        WriteStr( o_rFile, C_sLineEnd );
}

void
GenericInfo_Parser::WriteKey( ostream &    o_rFile,
                              const char *  i_sStr )
{
    WriteIndentation(o_rFile);
    WriteStr( o_rFile, i_sStr );
}

void
GenericInfo_Parser::WriteValue( ostream &    o_rFile,
                                const char *  i_sStr )
{
    if ( i_sStr != 0 ? strlen(i_sStr) > 0 : false )
    {
         WriteStr(o_rFile," ");
         WriteStr(o_rFile,i_sStr);
    }

    WriteStr(o_rFile,C_sLineEnd);
}

void
GenericInfo_Parser::WriteIndentation( ostream &    o_rFile )
{
    const int nIndentBound = 60;

    static const char sIndentation[nIndentBound+1] =
        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";

    if ( nLevel == 0 )
        return;

    if ( nLevel <= nIndentBound )
        o_rFile.write( sIndentation, nLevel );
    else
    {
        INT16 iLevel = nLevel;
        for ( ; iLevel > nIndentBound; iLevel-=nIndentBound )
            o_rFile.write( sIndentation, nIndentBound );
        o_rFile.write( sIndentation, iLevel );
    }
}

<|endoftext|>


<commit_before>/*
	The MIT License (MIT)
	Copyright (c) 2016 Gagan Kumar(scopeInfinity)
	Complete License at https://raw.githubusercontent.com/scopeInfinity/NaturalSort/master/LICENSE.md
*/

/**********************************************************************
Calling Methods :

	//For Natural Sorting
	void SI::natural::sort(Container<String>);
	void SI::natural::sort(IteratorBegin<String>,IteratorEnd<String>);
	void SI::natural::sort<String,CArraySize>(CArray<String>);

	//For Natural Comparision
	bool SI::natural::compare<String>(String lhs,String rhs);
	bool SI::natural::compare<String>(char *const lhs,char *const rhs);

	Here we can have
		std::vector<std::string> 	as Container<String>
		String 						as std::string
		CArray<String>				as std::string[CArraySize]

***********************************************************************/
#ifndef SI_sort_HPP
#define SI_sort_HPP
#include <cctype>
#include <algorithm>
#include <vector>

namespace SI
{
namespace natural
{
	namespace detail
	{
		/********** Compare Two Character CaseInsensitive ********/
		template<typename ElementType>
		bool natural_less(const ElementType &lhs,const ElementType &rhs)
		{
			if(tolower(lhs)<tolower(rhs))
				return true;
			return false;
		}

		template<typename ElementType>
		bool is_not_digit(const ElementType &x)
		{
			return !isdigit(x);
		}

		/********** Compare Two Iterators CaseInsensitive ********/
		template<typename ElementType,typename Iterator>
		struct comp_over_iterator
		{
			int operator()(const Iterator &lhs,const Iterator &rhs) const
			{
				if(natural_less<ElementType>(*lhs,*rhs))
					return -1;
				if(natural_less<ElementType>(*rhs,*lhs))
					return +1;
			}
		};

		/****************************************************
		Comparing two SubString from (Begin,End Iterator each)
		with only digits.
		Usage :
			int compare_number()(\
			FirstNumberBeginIterator,FirstNumberEndIterator,isFirstNumberFractionalPart\
			SecondNumberBeginIterator,SecondNumberEndIterator,isSecondNumberFractionalPart\
			);

		Returns :
			-1  - Number1  <   Number2
			 0  - Number1  ==  Number2
			 1  - Number1  >   Number2

		***************************************************/

		template<typename ValueType, typename Iterator>
		struct compare_number
		{
		private:
			//If Number is Itself fractional Part
			int fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
			{
				while(lhsBegin<lhsEnd && rhsBegin<rhsEnd)
				{
					int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
					if(local_compare!=0)
						return local_compare;
					lhsBegin++;
					rhsBegin++;
				}
				while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
				while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;
				if(lhsBegin==lhsEnd && rhsBegin!=rhsEnd)
					return -1;
				else if(lhsBegin!=lhsEnd && rhsBegin==rhsEnd)
					return +1;
				else //lhsBegin==lhsEnd && rhsBegin==rhsEnd
					return 0;
			}
			int non_fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
			{
				//Skip Inital Zero's
				while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
				while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;

				//Comparing By Length of Both String
				if(lhsEnd-lhsBegin<rhsEnd-rhsBegin)
					return -1;
				if(lhsEnd-lhsBegin>rhsEnd-rhsBegin)
					return +1;

				//Equal In length
				while(lhsBegin<lhsEnd)
				{
					int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
					if(local_compare!=0)
						return local_compare;
					lhsBegin++;
					rhsBegin++;
				}
				return 0;
			}

		public:
			int operator()(\
				Iterator lhsBegin,Iterator lhsEnd,bool isFractionalPart1,\
				Iterator rhsBegin,Iterator rhsEnd,bool isFractionalPart2)
			{
				if(isFractionalPart1 && !isFractionalPart2)
					return true;	//0<num1<1 && num2>=1
				if(!isFractionalPart1 && isFractionalPart2)
					return false;	//0<num2<1 && num1>=1

				//isFractionPart1 == isFactionalPart2
				if(isFractionalPart1)
					return fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
				else
					return non_fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
			}
		};

	}// namespace detail

	/***********************************************************************
	Natural Comparision of Two String using both's (Begin and End Iterator)

	Returns :
		-1  - String1  <   String2
		 0  - String1  ==  String2
		 1  - String1  >   String2

	Suffix 1 represents for components of 1st String
	Suffix 2 represents for components of 2nd String
	************************************************************************/

	template<typename ElementType, typename Iterator>
	bool _compare(\
		const Iterator &lhsBegin,const Iterator &lhsEnd,\
		const Iterator &rhsBegin,const Iterator &rhsEnd)
	{
		Iterator current1 = lhsBegin,current2 = rhsBegin;

		//Flag for Space Found Check
		bool flag_found_space1 = false,flag_found_space2 = false;

		while(current1!=lhsEnd && current2!=rhsEnd)
		{
			//Ignore More than One Continous Space

			/******************************************
			For HandlingComparision Like
				Hello   9
				Hello  10
				Hello 123
			******************************************/
			while(flag_found_space1 && current1!=lhsEnd && *current1==' ') current1++;
			flag_found_space1=false;
			if(*current1==' ') flag_found_space1 = true;

			while(flag_found_space2 && current2!=rhsEnd && *current2==' ') current2++;
			flag_found_space2=false;
			if(*current2==' ') flag_found_space2 = true;

			if( !isdigit(*current1 ) && !isdigit(*current2))
			{
				//If Both Are Non Digits do Normal Comparision
				if(detail::natural_less<ElementType>(*current1,*current2))
					return true;
				if(detail::natural_less<ElementType>(*current2,*current1))
					return false;
				current1++;
				current2++;
			}
			else
			{
				/*********************************
				Capture Numeric Part of Both String
				and then using it to compare Both

				***********************************/
				Iterator last_nondigit1 = 	std::find_if(current1,lhsEnd,detail::is_not_digit<ElementType>);
				Iterator last_nondigit2 = 	std::find_if(current2,rhsEnd,detail::is_not_digit<ElementType>);

				int result = detail::compare_number<ElementType, Iterator>()(\
					current1,last_nondigit1,(current1>lhsBegin && *(current1-1)=='.'), \
					current2,last_nondigit2,(current2>rhsBegin && *(current2-1)=='.'));
				if(result<0)
					return true;
				if(result>0)
					return false;
				current1 = last_nondigit1;
				current2 = last_nondigit2;
			}
		}

	}

	template<typename String>
	inline bool compare(const String &first ,const String &second)
	{
		return _compare<typename String::value_type,typename String::const_iterator>(first.begin(),first.end(),second.begin(),second.end());
	}
	template<>
	inline bool compare(char *const &first ,char *const &second)
	{
		char* it1 = first;
		while(*it1!='\0')it1++;
		char* it2 = second;
		while(*it2!='\0')it2++;
		return _compare<char,char*>(first,it1,second,it2);
	}

	template<typename Container>
	inline bool sort(Container &container)
	{
		std::sort(container.begin(),container.end(),compare<typename Container::value_type>);
	}

	template<typename Iterator>
	inline bool sort(const Iterator &first,const Iterator &end)
	{
		std::sort(first,end,compare<typename Iterator::value_type>);
	}

	template<typename ValueType>
	inline bool sort(ValueType* const first,ValueType* const end)
	{
		std::sort(first,end,compare<ValueType>);
	}

	template<typename ValueType,int N>
	inline bool sort(ValueType container[N])
	{
		std::sort(&container[0],&container[0]+N,compare<ValueType>);
	}

}//namespace natural
}//namespace SI

#endif
<commit_msg>Return properly value when lfs == rhs in comp_over_iterator().<commit_after>/*
	The MIT License (MIT)
	Copyright (c) 2016 Gagan Kumar(scopeInfinity)
	Complete License at https://raw.githubusercontent.com/scopeInfinity/NaturalSort/master/LICENSE.md
*/

/**********************************************************************
Calling Methods :

	//For Natural Sorting
	void SI::natural::sort(Container<String>);
	void SI::natural::sort(IteratorBegin<String>,IteratorEnd<String>);
	void SI::natural::sort<String,CArraySize>(CArray<String>);

	//For Natural Comparision
	bool SI::natural::compare<String>(String lhs,String rhs);
	bool SI::natural::compare<String>(char *const lhs,char *const rhs);

	Here we can have
		std::vector<std::string> 	as Container<String>
		String 						as std::string
		CArray<String>				as std::string[CArraySize]

***********************************************************************/
#ifndef SI_sort_HPP
#define SI_sort_HPP
#include <cctype>
#include <algorithm>
#include <vector>

namespace SI
{
namespace natural
{
	namespace detail
	{
		/********** Compare Two Character CaseInsensitive ********/
		template<typename ElementType>
		bool natural_less(const ElementType &lhs,const ElementType &rhs)
		{
			if(tolower(lhs)<tolower(rhs))
				return true;
			return false;
		}

		template<typename ElementType>
		bool is_not_digit(const ElementType &x)
		{
			return !isdigit(x);
		}

		/********** Compare Two Iterators CaseInsensitive ********/
		template<typename ElementType,typename Iterator>
		struct comp_over_iterator
		{
			int operator()(const Iterator &lhs,const Iterator &rhs) const
			{
				if(natural_less<ElementType>(*lhs,*rhs))
					return -1;
				if(natural_less<ElementType>(*rhs,*lhs))
					return +1;
				return 0;
			}
		};

		/****************************************************
		Comparing two SubString from (Begin,End Iterator each)
		with only digits.
		Usage :
			int compare_number()(\
			FirstNumberBeginIterator,FirstNumberEndIterator,isFirstNumberFractionalPart\
			SecondNumberBeginIterator,SecondNumberEndIterator,isSecondNumberFractionalPart\
			);

		Returns :
			-1  - Number1  <   Number2
			 0  - Number1  ==  Number2
			 1  - Number1  >   Number2

		***************************************************/

		template<typename ValueType, typename Iterator>
		struct compare_number
		{
		private:
			//If Number is Itself fractional Part
			int fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
			{
				while(lhsBegin<lhsEnd && rhsBegin<rhsEnd)
				{
					int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
					if(local_compare!=0)
						return local_compare;
					lhsBegin++;
					rhsBegin++;
				}
				while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
				while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;
				if(lhsBegin==lhsEnd && rhsBegin!=rhsEnd)
					return -1;
				else if(lhsBegin!=lhsEnd && rhsBegin==rhsEnd)
					return +1;
				else //lhsBegin==lhsEnd && rhsBegin==rhsEnd
					return 0;
			}
			int non_fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
			{
				//Skip Inital Zero's
				while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
				while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;

				//Comparing By Length of Both String
				if(lhsEnd-lhsBegin<rhsEnd-rhsBegin)
					return -1;
				if(lhsEnd-lhsBegin>rhsEnd-rhsBegin)
					return +1;

				//Equal In length
				while(lhsBegin<lhsEnd)
				{
					int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
					if(local_compare!=0)
						return local_compare;
					lhsBegin++;
					rhsBegin++;
				}
				return 0;
			}

		public:
			int operator()(\
				Iterator lhsBegin,Iterator lhsEnd,bool isFractionalPart1,\
				Iterator rhsBegin,Iterator rhsEnd,bool isFractionalPart2)
			{
				if(isFractionalPart1 && !isFractionalPart2)
					return true;	//0<num1<1 && num2>=1
				if(!isFractionalPart1 && isFractionalPart2)
					return false;	//0<num2<1 && num1>=1

				//isFractionPart1 == isFactionalPart2
				if(isFractionalPart1)
					return fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
				else
					return non_fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
			}
		};

	}// namespace detail

	/***********************************************************************
	Natural Comparision of Two String using both's (Begin and End Iterator)

	Returns :
		-1  - String1  <   String2
		 0  - String1  ==  String2
		 1  - String1  >   String2

	Suffix 1 represents for components of 1st String
	Suffix 2 represents for components of 2nd String
	************************************************************************/

	template<typename ElementType, typename Iterator>
	bool _compare(\
		const Iterator &lhsBegin,const Iterator &lhsEnd,\
		const Iterator &rhsBegin,const Iterator &rhsEnd)
	{
		Iterator current1 = lhsBegin,current2 = rhsBegin;

		//Flag for Space Found Check
		bool flag_found_space1 = false,flag_found_space2 = false;

		while(current1!=lhsEnd && current2!=rhsEnd)
		{
			//Ignore More than One Continous Space

			/******************************************
			For HandlingComparision Like
				Hello   9
				Hello  10
				Hello 123
			******************************************/
			while(flag_found_space1 && current1!=lhsEnd && *current1==' ') current1++;
			flag_found_space1=false;
			if(*current1==' ') flag_found_space1 = true;

			while(flag_found_space2 && current2!=rhsEnd && *current2==' ') current2++;
			flag_found_space2=false;
			if(*current2==' ') flag_found_space2 = true;

			if( !isdigit(*current1 ) && !isdigit(*current2))
			{
				//If Both Are Non Digits do Normal Comparision
				if(detail::natural_less<ElementType>(*current1,*current2))
					return true;
				if(detail::natural_less<ElementType>(*current2,*current1))
					return false;
				current1++;
				current2++;
			}
			else
			{
				/*********************************
				Capture Numeric Part of Both String
				and then using it to compare Both

				***********************************/
				Iterator last_nondigit1 = 	std::find_if(current1,lhsEnd,detail::is_not_digit<ElementType>);
				Iterator last_nondigit2 = 	std::find_if(current2,rhsEnd,detail::is_not_digit<ElementType>);

				int result = detail::compare_number<ElementType, Iterator>()(\
					current1,last_nondigit1,(current1>lhsBegin && *(current1-1)=='.'), \
					current2,last_nondigit2,(current2>rhsBegin && *(current2-1)=='.'));
				if(result<0)
					return true;
				if(result>0)
					return false;
				current1 = last_nondigit1;
				current2 = last_nondigit2;
			}
		}

	}

	template<typename String>
	inline bool compare(const String &first ,const String &second)
	{
		return _compare<typename String::value_type,typename String::const_iterator>(first.begin(),first.end(),second.begin(),second.end());
	}
	template<>
	inline bool compare(char *const &first ,char *const &second)
	{
		char* it1 = first;
		while(*it1!='\0')it1++;
		char* it2 = second;
		while(*it2!='\0')it2++;
		return _compare<char,char*>(first,it1,second,it2);
	}

	template<typename Container>
	inline bool sort(Container &container)
	{
		std::sort(container.begin(),container.end(),compare<typename Container::value_type>);
	}

	template<typename Iterator>
	inline bool sort(const Iterator &first,const Iterator &end)
	{
		std::sort(first,end,compare<typename Iterator::value_type>);
	}

	template<typename ValueType>
	inline bool sort(ValueType* const first,ValueType* const end)
	{
		std::sort(first,end,compare<ValueType>);
	}

	template<typename ValueType,int N>
	inline bool sort(ValueType container[N])
	{
		std::sort(&container[0],&container[0]+N,compare<ValueType>);
	}

}//namespace natural
}//namespace SI

#endif
<|endoftext|>