OpenRTX/lib/miosix-kernel/miosix/filesystem/stringpart.h

217 wiersze
9.0 KiB
C++

/***************************************************************************
* Copyright (C) 2013 by Terraneo Federico *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* As a special exception, if other files instantiate templates or use *
* macros or inline functions from this file, or you compile this file *
* and link it with other works to produce a work based on this file, *
* this file does not by itself cause the resulting work to be covered *
* by the GNU General Public License. However the source code for this *
* file must still be made available in accordance with the GNU General *
* Public License. This exception does not invalidate any other reasons *
* why a work based on this file might be covered by the GNU General *
* Public License. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef STRINGPART_H
#define STRINGPART_H
#include <string>
#include <cstring>
namespace miosix {
/**
* \internal
* This class is used to take a substring of a string containing a file path
* without creating a copy, and therefore requiring additional memory
* allocation.
*
* When parsing a path like "/home/test/directory/file" it is often necessary
* to create substrings at the path component boundaries, such as "/home/test".
* In this case, it is possible to temporarily make a substring by replacing a
* '/' with a '\0'. The std::string will not 'forget' its orginal size, and
* when the '\0' will be converted back to a '/', the string will look identical
* to the previous one.
*
* This is an optimization made for filesystem mountpoint lookups, and is not
* believed to be useful outside of that purpose. Given that in Miosix, the
* mountpoints are stored in a map, this class supports operator< to correctly
* lookup mountpoints in the map.
*/
class StringPart
{
public:
/**
* Default constructor
*/
StringPart() : cstr(&saved), index(0), offset(0), saved('\0'),
owner(false), type(CSTR)
{
//We need an empty C string, that is, a pointer to a char that is \0,
//so we make cstr point to saved, and set saved to \0.
}
/**
* Constructor from C++ string
* \param str original string. A pointer to the string is taken, the string
* is NOT copied. Therefore, the caller is responsible to guarantee the
* string won't be deallocated while this class is alive. Note that the
* original string is modified by inserting a '\0' at the index position,
* if index is given. The string will be restored to the exact original
* content only when this class is destroyed.
* \param idx if this parameter is given, this class becomes an in-place
* substring of the original string. Otherwise, this class will store the
* entire string passed. In this case, the original string will not be
* modified.
* \param off if this parameter is given, the first off characters of the
* string are skipped. Note that idx calculations take place <b>before</b>
* offset computation, so idx is relative to the original string.
*/
explicit StringPart(std::string& str, size_t idx=std::string::npos,
size_t off=0);
/**
* Constructor from C string
* \param s original string. A pointer to the string is taken, the string
* is NOT copied. Therefore, the caller is responsible to guarantee the
* string won't be deallocated while this class is alive. Note that the
* original string is modified by inserting a '\0' at the index position,
* if index is given. The string will be restored to the exact original
* content only when this class is destroyed.
* \param idx if this parameter is given, this class becomes an in-place
* substring of the original string. Otherwise, this class will store the
* entire string passed. In this case, the original string will not be
* modified.
* \param off if this parameter is given, the first off characters of the
* string are skipped. Note that idx calculations take place <b>before</b>
* offset computation, so idx is relative to the original string.
*/
explicit StringPart(char *s, size_t idx=std::string::npos, size_t off=0);
/**
* Constructor from const C string
* \param s original string. A pointer to the string is taken, the string
* is NOT copied. Therefore, the caller is responsible to guarantee the
* string won't be deallocated while this class is alive. Note that this
* constructor misses the idx and off parameters as it's not possible to
* make an in-place substring of a string if it's const.
*/
explicit StringPart(const char *s);
/**
* Substring constructor. Given a StringPart, produce another StringPart
* holding a substring of the original StringPart. Unlike the normal copy
* constructor that does deep copy, this one does shallow copy, and
* therefore the newly created object will share the same string pointer
* as rhs. Useful for making substrings of a substring without memory
* allocation.
* \param rhs a StringPart
*/
StringPart(StringPart& rhs, size_t idx, size_t off=0);
/**
* Copy constructor. Note that deep copying is used, so that the newly
* created StringPart is a self-contained string. It has been done like
* that to be able to store the paths of mounted filesystems in an std::map
* \param rhs a StringPart
*/
StringPart(const StringPart& rhs);
/**
* Operator = Note that deep copying is used, so that the assigned
* StringPart becomes a self-contained string. It has been done like
* that to be able to store the paths of mounted filesystems in an std::map
* \param rhs a StringPart
*/
StringPart& operator= (const StringPart& rhs);
/**
* Compare two StringParts for inequality
* \param rhs second StringPart to compare to
* \return true if *this < rhs
*/
bool operator<(const StringPart& rhs) const
{
return strcmp(this->c_str(),rhs.c_str())<0;
}
/**
* \param rhs a StringPart
* \return true if this starts with rhs
*/
bool startsWith(const StringPart& rhs) const;
/**
* \param c char to find in the string, starting from the end
* \return the index of the last occurrence of c, or string::npos
*/
size_t findLastOf(char c) const;
/**
* \return the StringPart length, which is the same as strlen(this->c_str())
*/
size_t length() const { return index-offset; }
/**
* \return the StringPart as a C string
*/
const char *c_str() const;
/**
* \param index index into the string
* \return the equivalent of this->c_str()[index]
*/
char operator[] (size_t index) const;
/**
* \return true if the string is empty
*/
bool empty() const { return length()==0; }
/**
* Make this an empty string
*/
void clear();
/**
* Destructor
*/
~StringPart() { clear(); }
private:
/**
* To implement copy constructor and operator=. *this must be empty.
* \param rhs other StringPart that is assigned to *this.
*/
void assign(const StringPart& rhs);
union {
std::string *str; ///< Pointer to underlying C++ string
char *cstr; ///< Pointer to underlying C string
const char *ccstr; ///< Pointer to underlying const C string
};
size_t index; ///< Index into the character substituted by '\0'
size_t offset; ///< Offset to skip the first part of a string
char saved; ///< Char that was replaced by '\0'
bool owner; ///< True if this class owns str
char type; ///< either CPPSTR or CSTR. Using char to reduce size
enum { CPPSTR, CSTR, CCSTR }; ///< Possible values fot type
};
} //namespace miosix
#endif //STRINGPART_H