Home | History | Annotate | Download | only in core
      1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
      2 
      3 Licensed under the Apache License, Version 2.0 (the "License");
      4 you may not use this file except in compliance with the License.
      5 You may obtain a copy of the License at
      6 
      7     http://www.apache.org/licenses/LICENSE-2.0
      8 
      9 Unless required by applicable law or agreed to in writing, software
     10 distributed under the License is distributed on an "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 See the License for the specific language governing permissions and
     13 limitations under the License.
     14 ==============================================================================*/
     15 
     16 // Wrapper functions to provide a scripting-language-friendly interface
     17 // to our string libraries.
     18 //
     19 // NOTE: as of 2005-01-13, this SWIG file is not used to generate a pywrap
     20 //       library for manipulation of various string-related types or access
     21 //       to the special string functions (Python has plenty). This SWIG file
     22 //       should be %import'd so that other SWIG wrappers have proper access
     23 //       to the types in //strings (such as the StringPiece object). We may
     24 //       generate a pywrap at some point in the future.
     25 //
     26 // NOTE: (Dan Ardelean) as of 2005-11-15 added typemaps to convert Java String
     27 //       arguments to C++ StringPiece& objects. This is required because a
     28 //       StringPiece class does not make sense - the code SWIG generates for a
     29 //       StringPiece class is useless, because it releases the buffer set in
     30 //       StringPiece after creating the object. C++ StringPiece objects rely on
     31 //       the buffer holding the data being allocated externally.
     32 
     33 // NOTE: for now, we'll just start with what is needed, and add stuff
     34 //       as it comes up.
     35 
     36 %{
     37 #include "tensorflow/core/lib/core/stringpiece.h"
     38 
     39 // Handles str in Python 2, bytes in Python 3.
     40 // Returns true on success, false on failure.
     41 bool _BytesToStringPiece(PyObject* obj, tensorflow::StringPiece* result) {
     42   if (obj == Py_None) {
     43     *result = tensorflow::StringPiece();
     44   } else {
     45     char* ptr;
     46     Py_ssize_t len;
     47     if (PyBytes_AsStringAndSize(obj, &ptr, &len) == -1) {
     48       // Python has raised an error (likely TypeError or UnicodeEncodeError).
     49       return false;
     50     }
     51     *result = tensorflow::StringPiece(ptr, len);
     52   }
     53   return true;
     54 }
     55 %}
     56 
     57 %typemap(typecheck) tensorflow::StringPiece = char *;
     58 %typemap(typecheck) const tensorflow::StringPiece & = char *;
     59 
     60 // "tensorflow::StringPiece" arguments must be specified as a 'str' or 'bytes' object.
     61 %typemap(in) tensorflow::StringPiece {
     62   if (!_BytesToStringPiece($input, &$1)) SWIG_fail;
     63 }
     64 
     65 // "const tensorflow::StringPiece&" arguments can be provided the same as
     66 // "tensorflow::StringPiece", whose typemap is defined above.
     67 %typemap(in) const tensorflow::StringPiece & (tensorflow::StringPiece temp) {
     68   if (!_BytesToStringPiece($input, &temp)) SWIG_fail;
     69   $1 = &temp;
     70 }
     71 
     72 // C++ functions returning tensorflow::StringPiece will simply return bytes in
     73 // Python, or None if the StringPiece contained a NULL pointer.
     74 %typemap(out) tensorflow::StringPiece {
     75   if ($1.data()) {
     76     $result = PyBytes_FromStringAndSize($1.data(), $1.size());
     77   } else {
     78     Py_INCREF(Py_None);
     79     $result = Py_None;
     80   }
     81 }
     82 
     83 // Converts a C++ string vector to a list of Python bytes objects.
     84 %typemap(out) std::vector<string> {
     85   const int size = $1.size();
     86   auto temp_string_list = tensorflow::make_safe(PyList_New(size));
     87   if (!temp_string_list) {
     88     SWIG_fail;
     89   }
     90   std::vector<tensorflow::Safe_PyObjectPtr> converted;
     91   converted.reserve(size);
     92   for (const string& op : $1) {
     93     // Always treat strings as bytes, consistent with the typemap
     94     // for string.
     95     PyObject* py_str = PyBytes_FromStringAndSize(op.data(), op.size());
     96     if (!py_str) {
     97       SWIG_fail;
     98     }
     99     converted.emplace_back(tensorflow::make_safe(py_str));
    100   }
    101   for (int i = 0; i < converted.size(); ++i) {
    102     PyList_SET_ITEM(temp_string_list.get(), i, converted[i].release());
    103   }
    104   $result = temp_string_list.release();
    105 }
    106