PyOW_String.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2003-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00035 #include <OW_String.hpp>
00036 #include <OW_Array.hpp>
00037 #include <OW_CIMDateTime.hpp>
00038 #include <OW_Char16.hpp>
00039 #include <OW_CIMObjectPath.hpp>
00040 // note this comes *after* the OpenWBEM headers, because it has a
00041 // #define ANY void
00042 // which really screws up OpenWBEM
00043 #include <boost/python.hpp>
00044 #ifdef ANY
00045 #undef ANY
00046 #endif
00047 
00048 namespace OW_NAMESPACE
00049 {
00050 
00051 using namespace boost::python;
00052  
00053 namespace {
00054 struct BoolToPython
00055 {
00056    static PyObject* convert(Bool const& x)
00057    {
00058       return Py_BuildValue("b", bool(x));
00059    }
00060 };
00061 // String
00062 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_tokenize_overloads, String::tokenize, 0, 2)
00063 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_endsWith_overloads, String::endsWith, 1, 2)
00064 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_indexOf_overloads, String::indexOf, 1, 2)
00065 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_lastIndexOf_overloads, String::lastIndexOf, 1, 2)
00066 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_startsWith_overloads, String::startsWith, 1, 2)
00067 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_substring_overloads, String::substring, 1, 2)
00068 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_erase_overloads, String::erase, 1, 2)
00069 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_toUInt8_overloads, String::toUInt8, 0, 1)
00070 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_toInt8_overloads, String::toInt8, 0, 1)
00071 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_toUInt16_overloads, String::toUInt16, 0, 1)
00072 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_toInt16_overloads, String::toInt16, 0, 1)
00073 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_toUInt32_overloads, String::toUInt32, 0, 1)
00074 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_toInt32_overloads, String::toInt32, 0, 1)
00075 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_toUInt64_overloads, String::toUInt64, 0, 1)
00076 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(String_toInt64_overloads, String::toInt64, 0, 1)
00077 String String_getslice(const String& s, int i, int j)
00078 {
00079    int len = s.length();
00080    if (i < 0)
00081    {
00082       i = 0;
00083    }
00084    if (j < 0)
00085    {
00086       j = 0;
00087    }
00088    if (i > j)
00089       return "";
00090    return s.substring(i, j - i);
00091 }
00092 PyObject* String_repr(const String& s)
00093 {
00094    String str("owclient.String(\"" + s + "\")");
00095    return Py_BuildValue("s#", str.c_str(), str.length());
00096 }
00097 int String_count(const String& s, char c)
00098 {
00099    int rval = 0;
00100    for (size_t i = 0; i < s.length(); ++i)
00101    {
00102       if (s[i] == c)
00103          ++rval;
00104    }
00105    return rval;
00106 }
00107 void String_append(String& s, char c)
00108 {
00109    s.concat(c);
00110 }
00111 int String_index(const String& s, char c)
00112 {
00113    for (size_t i = 0; i < s.length(); ++i)
00114    {
00115       if (s[i] == c)
00116          return i;
00117    }
00118    // Raise ValueError
00119    PyErr_SetString(PyExc_ValueError,
00120          "String.index(x): x not in list");
00121    boost::python::throw_error_already_set();
00122 }
00123 void String_insert(String& s, int i, char x)
00124 {
00125    size_t length = s.length();
00126    if (i < 0)
00127    {
00128       i = 0;
00129    }
00130    s = s.substring(0, i) + String(x) + s.substring(i);
00131 }
00132 char String_pop(String& s, int i = -1)
00133 {
00134    size_t length = s.length();
00135    while (true)
00136    {
00137       if (i < 0)
00138       {
00139          i += length;
00140       }
00141       else if (i >= length)
00142       {
00143          i -= length;
00144       }
00145       else
00146       {
00147          break;
00148       }
00149    }
00150    char rval = s[i];
00151    s = s.substring(0, i) + s.substring(i+1);
00152    return rval;
00153 }
00154 BOOST_PYTHON_FUNCTION_OVERLOADS(String_pop_overloads, String_pop, 1, 2)
00155 void String_remove(String& s, char x)
00156 {
00157    int i = String_index(s, x);
00158    s = s.substring(0, i) + s.substring(i+1);
00159 }
00160 void String_reverse(String& s)
00161 {
00162    std::reverse(&s[0], &s[s.length()]);
00163 }
00164 void String_sort(String& s)
00165 {
00166    std::sort(&s[0], &s[s.length()]);
00167 }
00168 char String_getitem_(const String& s, int i)
00169 {
00170    if (i < 0 || i >= s.length())
00171    {
00172       // raise IndexError
00173       PyErr_SetString(PyExc_IndexError,
00174             "String index out of range");
00175       boost::python::throw_error_already_set();
00176    }
00177    return s[i];
00178 }
00179 void String_setitem_(String& s, int i, char c)
00180 {
00181    if (i < 0 || i >= s.length())
00182    {
00183       // raise IndexError
00184       PyErr_SetString(PyExc_IndexError,
00185             "String index out of range");
00186       boost::python::throw_error_already_set();
00187    }
00188    s[i] = c;
00189 }
00190 void String_delitem_(String& s, int i)
00191 {
00192    if (i < 0 || i >= s.length())
00193    {
00194       // raise IndexError
00195       PyErr_SetString(PyExc_IndexError,
00196             "String index out of range");
00197       boost::python::throw_error_already_set();
00198    }
00199    s = s.substring(0, i) + s.substring(i+1);
00200 }
00201 }
00202 void registerString()
00203 {
00204    class_<String>("String")
00205       .def(init<Int32>())
00206       .def(init<UInt32>())
00207       .def(init<Int64>())
00208       .def(init<UInt64>())
00209       .def(init<Real64>())
00210       .def(init<const char*>())
00211 // Uncomment this to activate implicit string conversion
00212 //        .def(init<const std::string&>())
00213       .def(init<const Char16Array&>())
00214       .def(init<Bool>())
00215       .def(init<const Char16&>())
00216       .def(init<const CIMDateTime&>())
00217       .def(init<const CIMObjectPath&>())
00218       .def(init<Bool, char*, size_t>())
00219       .def(init<const char*, size_t>())
00220 // this seems to prevent the const char* ctor from working, and we don't
00221 // really need it since a char and a char* are the same in python.
00222 //        .def(init<char>())
00223       .def("length", &String::length)
00224       .def("__len__", &String::length)
00225       .def("empty", &String::empty)
00226 // Can't wrap variable argument functions
00227 //        .def("format", &String::format)
00228       .def("tokenize", &String::tokenize, String_tokenize_overloads(args("delims", "returnTokens")))
00229       .def("c_str", &String::c_str)
00230       .def("getBytes", &String::getBytes)
00231       .def("charAt", &String::charAt)
00232       .def("compareTo", &String::compareTo)
00233       .def("compareToIgnoreCase", &String::compareToIgnoreCase)
00234       .def("concat", (String& (String::*)(const String&))(&String::concat), return_internal_reference<>())
00235       .def("endsWith", &String::endsWith, String_endsWith_overloads(args("arg", "ignoreCase")))
00236       .def("equals", &String::equals)
00237       .def("equalsIgnoreCase", &String::equalsIgnoreCase)
00238       .def("hashCode", &String::hashCode)
00239       .def("indexOf", (int (String::*)(char, int) const)(&String::indexOf), String_indexOf_overloads(args("ch", "fromIndex")))
00240       .def("indexOf", (int (String::*)(const String&, int) const)(&String::indexOf), String_indexOf_overloads(args("arg", "fromIndex")))
00241       .def("lastIndexOf", (int (String::*)(char, int) const)(&String::lastIndexOf), String_lastIndexOf_overloads(args("ch", "fromIndex")))
00242       .def("lastIndexOf", (int (String::*)(const String&, int) const)(&String::lastIndexOf), String_lastIndexOf_overloads(args("arg", "fromIndex")))
00243       .def("startsWith", &String::startsWith, String_startsWith_overloads(args("arg", "ignoreCase")))
00244       .def("substring", &String::substring, String_substring_overloads(args("beginIndex", "length")))
00245       // The next few methods are to support enumlating a python container type
00246       .def("__getslice__", &String_getslice)
00247       // TODO: add __setslice__ and __delslice__ 
00248       .def("append", &String_append)
00249       .def("count", &String_count)
00250       .def("index", &String_index)
00251       .def("insert", &String_insert)
00252       .def("pop", &String_pop, String_pop_overloads(args("i")))
00253       .def("remove", &String_remove)
00254       .def("reverse", &String_reverse)
00255       .def("sort", &String_sort)
00256       .def("isSpaces", &String::isSpaces)
00257       .def("toLowerCase", &String::toLowerCase, return_internal_reference<>())
00258       .def("toUpperCase", &String::toUpperCase, return_internal_reference<>())
00259       .def("ltrim", &String::ltrim, return_internal_reference<>())
00260       .def("rtrim", &String::rtrim, return_internal_reference<>())
00261       .def("trim", &String::trim, return_internal_reference<>())
00262       .def("erase", (String& (String::*)())(&String::erase), return_internal_reference<>())
00263       .def("erase", (String& (String::*)(size_t, size_t))(&String::erase), String_erase_overloads(args("idx", "len"))[return_internal_reference<>()])
00264       .def("__getitem__", &String_getitem_)
00265       .def("__setitem__", &String_setitem_)
00266       .def("__delitem__", &String_delitem_)
00267       .def(self += self)
00268       .def("readObject", &String::readObject)
00269       .def("writeObject", &String::writeObject)
00270       .def("toString", &String::toString)
00271       .def("toChar16", &String::toChar16)
00272       .def("toReal32", &String::toReal32)
00273       .def("toReal64", &String::toReal64)
00274       .def("toBool", &String::toBool)
00275       .def("toUInt8", &String::toUInt8, String_toUInt8_overloads(args("base")))
00276       .def("toInt8", &String::toInt8, String_toInt8_overloads(args("base")))
00277       .def("toUInt16", &String::toUInt16, String_toUInt16_overloads(args("base")))
00278       .def("toInt16", &String::toInt16, String_toInt16_overloads(args("base")))
00279       .def("toUInt32", &String::toUInt32, String_toUInt32_overloads(args("base")))
00280       .def("toInt32", &String::toInt32, String_toInt32_overloads(args("base")))
00281       .def("toUInt64", &String::toUInt64, String_toUInt64_overloads(args("base")))
00282       .def("toInt64", &String::toInt64, String_toInt64_overloads(args("base")))
00283       .def("toDateTime", &String::toDateTime)
00284       .def("strtoull", &String::strtoull)
00285       .def("strtoll", &String::strtoll)
00286       .def("getLine", &String::getLine)
00287       .def(self_ns::str(self))
00288       .def("__repr__", &String_repr)
00289       .def(self + self)
00290       .def((const char*)0 + self)
00291       .def(self + (const char*)0)
00292       .def(char() + self)
00293       .def(self + char())
00294       .def(self == self)
00295       .def(self == (const char*)0)
00296       .def((const char*)0 == self)
00297       .def(self != self)
00298       .def(self != (const char*)0)
00299       .def((const char*)0 != self)
00300       .def(self < self)
00301       .def(self < (const char*)0)
00302       .def((const char*)0 < self)
00303       .def(self <= self)
00304       .def(self <= (const char*)0)
00305       .def((const char*)0 <= self)
00306       .def(self > self)
00307       .def(self > (const char*)0)
00308       .def((const char*)0 > self)
00309       .def(self >= self)
00310       .def(self >= (const char*)0)
00311       .def((const char*)0 >= self)
00312       ;
00313    to_python_converter<Bool, BoolToPython>();
00314 //    To make a python string implicitly convertible to String, add a
00315 //    constructor to String that takes a std::string, and then uncomment
00316 //    this.
00317 //    implicitly_convertible<std::string, String>();
00318 }
00319 
00320 } // end namespace OW_NAMESPACE
00321 

Generated on Thu Feb 9 08:48:30 2006 for openwbem by  doxygen 1.4.6