Home | History | Annotate | Download | only in memory_image
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 // MemoryImageReader, class for reading a memory image.
     18 
     19 #ifndef LIBTEXTCLASSIFIER_COMMON_MEMORY_IMAGE_MEMORY_IMAGE_READER_H_
     20 #define LIBTEXTCLASSIFIER_COMMON_MEMORY_IMAGE_MEMORY_IMAGE_READER_H_
     21 
     22 #include <string>
     23 #include <vector>
     24 
     25 #include "common/memory_image/memory-image-common.h"
     26 #include "common/memory_image/memory-image.pb.h"
     27 #include "util/base/integral_types.h"
     28 #include "util/base/logging.h"
     29 #include "util/base/macros.h"
     30 
     31 namespace libtextclassifier {
     32 namespace nlp_core {
     33 
     34 // General, non-templatized class, to reduce code duplication.
     35 //
     36 // Given a memory area (pointer to start + size in bytes) parses a memory image
     37 // from there into (1) MemoryImageHeader proto (it includes the serialized form
     38 // of the trimmed down original proto) and (2) a list of void* pointers to the
     39 // beginning of all data blobs.
     40 //
     41 // In case of parsing errors, we prefer to log the error and set the
     42 // success_status() to false, instead of CHECK-failing .  This way, the client
     43 // has the option of performing error recovery or crashing.  Some mobile apps
     44 // don't like crashing (a restart is very slow) so, if possible, we try to avoid
     45 // that.
     46 class GeneralMemoryImageReader {
     47  public:
     48   // Constructs this object.  See class-level comments.  Note: the memory area
     49   // pointed to by start should not be deallocated while this object is used:
     50   // this object does not copy it; instead, it keeps pointers inside that memory
     51   // area.
     52   GeneralMemoryImageReader(const void *start, uint64 num_bytes)
     53       : start_(start), num_bytes_(num_bytes) {
     54     success_ = ReadMemoryImage();
     55   }
     56 
     57   virtual ~GeneralMemoryImageReader() {}
     58 
     59   // Returns true if reading the memory image has been successful.  If this
     60   // returns false, then none of the other accessors should be used.
     61   bool success_status() const { return success_; }
     62 
     63   // Returns number of data blobs from the memory image.
     64   int num_data_blobs() const {
     65     return data_blob_views_.size();
     66   }
     67 
     68   // Returns pointer to the beginning of the data blob #i.
     69   DataBlobView data_blob_view(int i) const {
     70     if ((i < 0) || (i >= num_data_blobs())) {
     71       TC_LOG(ERROR) << "Blob index " << i << " outside range [0, "
     72                     << num_data_blobs() << "); will return empty data chunk";
     73       return DataBlobView();
     74     }
     75     return data_blob_views_[i];
     76   }
     77 
     78   // Returns std::string with binary serialization of the original proto, but
     79   // trimmed of the large fields (those were placed in the data blobs).
     80   std::string trimmed_proto_str() const {
     81     return trimmed_proto_serialization_.ToString();
     82   }
     83 
     84   const MemoryImageHeader &header() { return header_; }
     85 
     86  protected:
     87   void set_as_failed() {
     88     success_ = false;
     89   }
     90 
     91  private:
     92   bool ReadMemoryImage();
     93 
     94   // Pointer to beginning of memory image.  Not owned.
     95   const void *const start_;
     96 
     97   // Number of bytes in the memory image.  This class will not read more bytes.
     98   const uint64 num_bytes_;
     99 
    100   // MemoryImageHeader parsed from the memory image.
    101   MemoryImageHeader header_;
    102 
    103   // Binary serialization of the trimmed version of the original proto.
    104   // Represented as a DataBlobView backed up by the underlying memory image
    105   // bytes.
    106   DataBlobView trimmed_proto_serialization_;
    107 
    108   // List of DataBlobView objects for all data blobs from the memory image (in
    109   // order).
    110   std::vector<DataBlobView> data_blob_views_;
    111 
    112   // Memory reading success status.
    113   bool success_;
    114 
    115   TC_DISALLOW_COPY_AND_ASSIGN(GeneralMemoryImageReader);
    116 };
    117 
    118 // Like GeneralMemoryImageReader, but has knowledge about the type of the
    119 // original proto.  As such, it can parse it (well, the trimmed version) and
    120 // offer access to it.
    121 //
    122 // Template parameter T should be the type of the original proto.
    123 template<class T>
    124 class MemoryImageReader : public GeneralMemoryImageReader {
    125  public:
    126   MemoryImageReader(const void *start, uint64 num_bytes)
    127       : GeneralMemoryImageReader(start, num_bytes) {
    128     if (!trimmed_proto_.ParseFromString(trimmed_proto_str())) {
    129       TC_LOG(INFO) << "Unable to parse the trimmed proto";
    130       set_as_failed();
    131     }
    132   }
    133 
    134   // Returns const reference to the trimmed version of the original proto.
    135   // Useful for retrieving the many small fields that are not converted into
    136   // data blobs.
    137   const T &trimmed_proto() const { return trimmed_proto_; }
    138 
    139  private:
    140   T trimmed_proto_;
    141 
    142   TC_DISALLOW_COPY_AND_ASSIGN(MemoryImageReader);
    143 };
    144 
    145 }  // namespace nlp_core
    146 }  // namespace libtextclassifier
    147 
    148 #endif  // LIBTEXTCLASSIFIER_COMMON_MEMORY_IMAGE_MEMORY_IMAGE_READER_H_
    149