widget/gonk/libui/Tokenizer.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /*
     2  * Copyright (C) 2010 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  */
    17 #define LOG_TAG "Tokenizer"
    18 #include "cutils_log.h"
    20 #include <stdlib.h>
    21 #include <unistd.h>
    22 #include <fcntl.h>
    23 #include <errno.h>
    24 #include <sys/types.h>
    25 #include <sys/stat.h>
    26 #include "Tokenizer.h"
    28 // Enables debug output for the tokenizer.
    29 #define DEBUG_TOKENIZER 0
    32 namespace android {
    34 static inline bool isDelimiter(char ch, const char* delimiters) {
    35     return strchr(delimiters, ch) != NULL;
    36 }
    38 Tokenizer::Tokenizer(const String8& filename, FileMap* fileMap, char* buffer,
    39         bool ownBuffer, size_t length) :
    40         mFilename(filename), mFileMap(fileMap),
    41         mBuffer(buffer), mOwnBuffer(ownBuffer), mLength(length),
    42         mCurrent(buffer), mLineNumber(1) {
    43 }
    45 Tokenizer::~Tokenizer() {
    46     if (mFileMap) {
    47         mFileMap->release();
    48     }
    49     if (mOwnBuffer) {
    50         delete[] mBuffer;
    51     }
    52 }
    54 status_t Tokenizer::open(const String8& filename, Tokenizer** outTokenizer) {
    55     *outTokenizer = NULL;
    57     int result = NO_ERROR;
    58     int fd = ::open(filename.string(), O_RDONLY);
    59     if (fd < 0) {
    60         result = -errno;
    61         ALOGE("Error opening file '%s', %s.", filename.string(), strerror(errno));
    62     } else {
    63         struct stat stat;
    64         if (fstat(fd, &stat)) {
    65             result = -errno;
    66             ALOGE("Error getting size of file '%s', %s.", filename.string(), strerror(errno));
    67         } else {
    68             size_t length = size_t(stat.st_size);
    70             FileMap* fileMap = new FileMap();
    71             bool ownBuffer = false;
    72             char* buffer;
    73             if (fileMap->create(NULL, fd, 0, length, true)) {
    74                 fileMap->advise(FileMap::SEQUENTIAL);
    75                 buffer = static_cast<char*>(fileMap->getDataPtr());
    76             } else {
    77                 fileMap->release();
    78                 fileMap = NULL;
    80                 // Fall back to reading into a buffer since we can't mmap files in sysfs.
    81                 // The length we obtained from stat is wrong too (it will always be 4096)
    82                 // so we must trust that read will read the entire file.
    83                 buffer = new char[length];
    84                 ownBuffer = true;
    85                 ssize_t nrd = read(fd, buffer, length);
    86                 if (nrd < 0) {
    87                     result = -errno;
    88                     ALOGE("Error reading file '%s', %s.", filename.string(), strerror(errno));
    89                     delete[] buffer;
    90                     buffer = NULL;
    91                 } else {
    92                     length = size_t(nrd);
    93                 }
    94             }
    96             if (!result) {
    97                 *outTokenizer = new Tokenizer(filename, fileMap, buffer, ownBuffer, length);
    98             }
    99         }
   100         close(fd);
   101     }
   102     return result;
   103 }
   105 status_t Tokenizer::fromContents(const String8& filename,
   106         const char* contents, Tokenizer** outTokenizer) {
   107     *outTokenizer = new Tokenizer(filename, NULL,
   108             const_cast<char*>(contents), false, strlen(contents));
   109     return OK;
   110 }
   112 String8 Tokenizer::getLocation() const {
   113     String8 result;
   114     result.appendFormat("%s:%d", mFilename.string(), mLineNumber);
   115     return result;
   116 }
   118 String8 Tokenizer::peekRemainderOfLine() const {
   119     const char* end = getEnd();
   120     const char* eol = mCurrent;
   121     while (eol != end) {
   122         char ch = *eol;
   123         if (ch == '\n') {
   124             break;
   125         }
   126         eol += 1;
   127     }
   128     return String8(mCurrent, eol - mCurrent);
   129 }
   131 String8 Tokenizer::nextToken(const char* delimiters) {
   132 #if DEBUG_TOKENIZER
   133     ALOGD("nextToken");
   134 #endif
   135     const char* end = getEnd();
   136     const char* tokenStart = mCurrent;
   137     while (mCurrent != end) {
   138         char ch = *mCurrent;
   139         if (ch == '\n' || isDelimiter(ch, delimiters)) {
   140             break;
   141         }
   142         mCurrent += 1;
   143     }
   144     return String8(tokenStart, mCurrent - tokenStart);
   145 }
   147 void Tokenizer::nextLine() {
   148 #if DEBUG_TOKENIZER
   149     ALOGD("nextLine");
   150 #endif
   151     const char* end = getEnd();
   152     while (mCurrent != end) {
   153         char ch = *(mCurrent++);
   154         if (ch == '\n') {
   155             mLineNumber += 1;
   156             break;
   157         }
   158     }
   159 }
   161 void Tokenizer::skipDelimiters(const char* delimiters) {
   162 #if DEBUG_TOKENIZER
   163     ALOGD("skipDelimiters");
   164 #endif
   165     const char* end = getEnd();
   166     while (mCurrent != end) {
   167         char ch = *mCurrent;
   168         if (ch == '\n' || !isDelimiter(ch, delimiters)) {
   169             break;
   170         }
   171         mCurrent += 1;
   172     }
   173 }
   175 } // namespace android

mercurial