LCOV - code coverage report
Current view: top level - media/libstagefright/system/core/libutils - String16.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 7 238 2.9 %
Date: 2017-07-14 16:53:18 Functions: 1 29 3.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2005 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             : #include <utils/String16.h>
      18             : 
      19             : #include <utils/Debug.h>
      20             : #include <utils/Log.h>
      21             : #include <utils/Unicode.h>
      22             : #include <utils/String8.h>
      23             : #include <utils/threads.h>
      24             : 
      25             : #include <memory.h>
      26             : #include <stdio.h>
      27             : #include <ctype.h>
      28             : 
      29             : 
      30             : namespace stagefright {
      31             : 
      32             : static SharedBuffer* gEmptyStringBuf = NULL;
      33             : static char16_t* gEmptyString = NULL;
      34             : 
      35           0 : static inline char16_t* getEmptyString()
      36             : {
      37           0 :     gEmptyStringBuf->acquire();
      38           0 :    return gEmptyString;
      39             : }
      40             : 
      41           3 : void initialize_string16()
      42             : {
      43           3 :     SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
      44           3 :     char16_t* str = (char16_t*)buf->data();
      45           3 :     *str = 0;
      46           3 :     gEmptyStringBuf = buf;
      47           3 :     gEmptyString = str;
      48           3 : }
      49             : 
      50           0 : void terminate_string16()
      51             : {
      52           0 :     SharedBuffer::bufferFromData(gEmptyString)->release();
      53           0 :     gEmptyStringBuf = NULL;
      54           0 :     gEmptyString = NULL;
      55           0 : }
      56             : 
      57             : // ---------------------------------------------------------------------------
      58             : 
      59           0 : static char16_t* allocFromUTF8(const char* u8str, size_t u8len)
      60             : {
      61           0 :     if (u8len == 0) return getEmptyString();
      62             : 
      63           0 :     const uint8_t* u8cur = (const uint8_t*) u8str;
      64             : 
      65           0 :     const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len);
      66           0 :     if (u16len < 0) {
      67           0 :         return getEmptyString();
      68             :     }
      69             : 
      70           0 :     const uint8_t* const u8end = u8cur + u8len;
      71             : 
      72           0 :     SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));
      73           0 :     if (buf) {
      74           0 :         u8cur = (const uint8_t*) u8str;
      75           0 :         char16_t* u16str = (char16_t*)buf->data();
      76             : 
      77           0 :         utf8_to_utf16(u8cur, u8len, u16str);
      78             : 
      79             :         //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
      80             :         //printHexData(1, str, buf->size(), 16, 1);
      81             :         //printf("\n");
      82             :         
      83           0 :         return u16str;
      84             :     }
      85             : 
      86           0 :     return getEmptyString();
      87             : }
      88             : 
      89             : // ---------------------------------------------------------------------------
      90             : 
      91           0 : String16::String16()
      92           0 :     : mString(getEmptyString())
      93             : {
      94           0 : }
      95             : 
      96           0 : String16::String16(StaticLinkage)
      97           0 :     : mString(0)
      98             : {
      99             :     // this constructor is used when we can't rely on the static-initializers
     100             :     // having run. In this case we always allocate an empty string. It's less
     101             :     // efficient than using getEmptyString(), but we assume it's uncommon.
     102             : 
     103             :     char16_t* data = static_cast<char16_t*>(
     104           0 :             SharedBuffer::alloc(sizeof(char16_t))->data());
     105           0 :     data[0] = 0;
     106           0 :     mString = data;
     107           0 : }
     108             : 
     109           0 : String16::String16(const String16& o)
     110           0 :     : mString(o.mString)
     111             : {
     112           0 :     SharedBuffer::bufferFromData(mString)->acquire();
     113           0 : }
     114             : 
     115           0 : String16::String16(const String16& o, size_t len, size_t begin)
     116           0 :     : mString(getEmptyString())
     117             : {
     118           0 :     setTo(o, len, begin);
     119           0 : }
     120             : 
     121           0 : String16::String16(const char16_t* o)
     122             : {
     123           0 :     size_t len = strlen16(o);
     124           0 :     SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
     125             :     ALOG_ASSERT(buf, "Unable to allocate shared buffer");
     126           0 :     if (buf) {
     127           0 :         char16_t* str = (char16_t*)buf->data();
     128           0 :         strcpy16(str, o);
     129           0 :         mString = str;
     130           0 :         return;
     131             :     }
     132             :     
     133           0 :     mString = getEmptyString();
     134             : }
     135             : 
     136           0 : String16::String16(const char16_t* o, size_t len)
     137             : {
     138           0 :     SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
     139             :     ALOG_ASSERT(buf, "Unable to allocate shared buffer");
     140           0 :     if (buf) {
     141           0 :         char16_t* str = (char16_t*)buf->data();
     142           0 :         memcpy(str, o, len*sizeof(char16_t));
     143           0 :         str[len] = 0;
     144           0 :         mString = str;
     145           0 :         return;
     146             :     }
     147             :     
     148           0 :     mString = getEmptyString();
     149             : }
     150             : 
     151           0 : String16::String16(const String8& o)
     152           0 :     : mString(allocFromUTF8(o.string(), o.size()))
     153             : {
     154           0 : }
     155             : 
     156           0 : String16::String16(const char* o)
     157           0 :     : mString(allocFromUTF8(o, strlen(o)))
     158             : {
     159           0 : }
     160             : 
     161           0 : String16::String16(const char* o, size_t len)
     162           0 :     : mString(allocFromUTF8(o, len))
     163             : {
     164           0 : }
     165             : 
     166           0 : String16::~String16()
     167             : {
     168           0 :     SharedBuffer::bufferFromData(mString)->release();
     169           0 : }
     170             : 
     171           0 : void String16::setTo(const String16& other)
     172             : {
     173           0 :     SharedBuffer::bufferFromData(other.mString)->acquire();
     174           0 :     SharedBuffer::bufferFromData(mString)->release();
     175           0 :     mString = other.mString;
     176           0 : }
     177             : 
     178           0 : status_t String16::setTo(const String16& other, size_t len, size_t begin)
     179             : {
     180           0 :     const size_t N = other.size();
     181           0 :     if (begin >= N) {
     182           0 :         SharedBuffer::bufferFromData(mString)->release();
     183           0 :         mString = getEmptyString();
     184           0 :         return NO_ERROR;
     185             :     }
     186           0 :     if ((begin+len) > N) len = N-begin;
     187           0 :     if (begin == 0 && len == N) {
     188           0 :         setTo(other);
     189           0 :         return NO_ERROR;
     190             :     }
     191             : 
     192           0 :     if (&other == this) {
     193           0 :         LOG_ALWAYS_FATAL("Not implemented");
     194             :     }
     195             : 
     196           0 :     return setTo(other.string()+begin, len);
     197             : }
     198             : 
     199           0 : status_t String16::setTo(const char16_t* other)
     200             : {
     201           0 :     return setTo(other, strlen16(other));
     202             : }
     203             : 
     204           0 : status_t String16::setTo(const char16_t* other, size_t len)
     205             : {
     206           0 :     SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
     207           0 :         ->editResize((len+1)*sizeof(char16_t));
     208           0 :     if (buf) {
     209           0 :         char16_t* str = (char16_t*)buf->data();
     210           0 :         memmove(str, other, len*sizeof(char16_t));
     211           0 :         str[len] = 0;
     212           0 :         mString = str;
     213           0 :         return NO_ERROR;
     214             :     }
     215           0 :     return NO_MEMORY;
     216             : }
     217             : 
     218           0 : status_t String16::append(const String16& other)
     219             : {
     220           0 :     const size_t myLen = size();
     221           0 :     const size_t otherLen = other.size();
     222           0 :     if (myLen == 0) {
     223           0 :         setTo(other);
     224           0 :         return NO_ERROR;
     225           0 :     } else if (otherLen == 0) {
     226           0 :         return NO_ERROR;
     227             :     }
     228             :     
     229           0 :     SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
     230           0 :         ->editResize((myLen+otherLen+1)*sizeof(char16_t));
     231           0 :     if (buf) {
     232           0 :         char16_t* str = (char16_t*)buf->data();
     233           0 :         memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
     234           0 :         mString = str;
     235           0 :         return NO_ERROR;
     236             :     }
     237           0 :     return NO_MEMORY;
     238             : }
     239             : 
     240           0 : status_t String16::append(const char16_t* chrs, size_t otherLen)
     241             : {
     242           0 :     const size_t myLen = size();
     243           0 :     if (myLen == 0) {
     244           0 :         setTo(chrs, otherLen);
     245           0 :         return NO_ERROR;
     246           0 :     } else if (otherLen == 0) {
     247           0 :         return NO_ERROR;
     248             :     }
     249             :     
     250           0 :     SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
     251           0 :         ->editResize((myLen+otherLen+1)*sizeof(char16_t));
     252           0 :     if (buf) {
     253           0 :         char16_t* str = (char16_t*)buf->data();
     254           0 :         memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
     255           0 :         str[myLen+otherLen] = 0;
     256           0 :         mString = str;
     257           0 :         return NO_ERROR;
     258             :     }
     259           0 :     return NO_MEMORY;
     260             : }
     261             : 
     262           0 : status_t String16::insert(size_t pos, const char16_t* chrs)
     263             : {
     264           0 :     return insert(pos, chrs, strlen16(chrs));
     265             : }
     266             : 
     267           0 : status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
     268             : {
     269           0 :     const size_t myLen = size();
     270           0 :     if (myLen == 0) {
     271           0 :         return setTo(chrs, len);
     272             :         return NO_ERROR;
     273           0 :     } else if (len == 0) {
     274           0 :         return NO_ERROR;
     275             :     }
     276             : 
     277           0 :     if (pos > myLen) pos = myLen;
     278             : 
     279             :     #if 0
     280             :     printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
     281             :            String8(*this).string(), pos,
     282             :            len, myLen, String8(chrs, len).string());
     283             :     #endif
     284             : 
     285           0 :     SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
     286           0 :         ->editResize((myLen+len+1)*sizeof(char16_t));
     287           0 :     if (buf) {
     288           0 :         char16_t* str = (char16_t*)buf->data();
     289           0 :         if (pos < myLen) {
     290           0 :             memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
     291             :         }
     292           0 :         memcpy(str+pos, chrs, len*sizeof(char16_t));
     293           0 :         str[myLen+len] = 0;
     294           0 :         mString = str;
     295             :         #if 0
     296             :         printf("Result (%d chrs): %s\n", size(), String8(*this).string());
     297             :         #endif
     298           0 :         return NO_ERROR;
     299             :     }
     300           0 :     return NO_MEMORY;
     301             : }
     302             : 
     303           0 : ssize_t String16::findFirst(char16_t c) const
     304             : {
     305           0 :     const char16_t* str = string();
     306           0 :     const char16_t* p = str;
     307           0 :     const char16_t* e = p + size();
     308           0 :     while (p < e) {
     309           0 :         if (*p == c) {
     310           0 :             return p-str;
     311             :         }
     312           0 :         p++;
     313             :     }
     314           0 :     return -1;
     315             : }
     316             : 
     317           0 : ssize_t String16::findLast(char16_t c) const
     318             : {
     319           0 :     const char16_t* str = string();
     320           0 :     const char16_t* p = str;
     321           0 :     const char16_t* e = p + size();
     322           0 :     while (p < e) {
     323           0 :         e--;
     324           0 :         if (*e == c) {
     325           0 :             return e-str;
     326             :         }
     327             :     }
     328           0 :     return -1;
     329             : }
     330             : 
     331           0 : bool String16::startsWith(const String16& prefix) const
     332             : {
     333           0 :     const size_t ps = prefix.size();
     334           0 :     if (ps > size()) return false;
     335           0 :     return strzcmp16(mString, ps, prefix.string(), ps) == 0;
     336             : }
     337             : 
     338           0 : bool String16::startsWith(const char16_t* prefix) const
     339             : {
     340           0 :     const size_t ps = strlen16(prefix);
     341           0 :     if (ps > size()) return false;
     342           0 :     return strncmp16(mString, prefix, ps) == 0;
     343             : }
     344             : 
     345           0 : status_t String16::makeLower()
     346             : {
     347           0 :     const size_t N = size();
     348           0 :     const char16_t* str = string();
     349           0 :     char16_t* edit = NULL;
     350           0 :     for (size_t i=0; i<N; i++) {
     351           0 :         const char16_t v = str[i];
     352           0 :         if (v >= 'A' && v <= 'Z') {
     353           0 :             if (!edit) {
     354           0 :                 SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
     355           0 :                 if (!buf) {
     356           0 :                     return NO_MEMORY;
     357             :                 }
     358           0 :                 edit = (char16_t*)buf->data();
     359           0 :                 mString = str = edit;
     360             :             }
     361           0 :             edit[i] = tolower((char)v);
     362             :         }
     363             :     }
     364           0 :     return NO_ERROR;
     365             : }
     366             : 
     367           0 : status_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
     368             : {
     369           0 :     const size_t N = size();
     370           0 :     const char16_t* str = string();
     371           0 :     char16_t* edit = NULL;
     372           0 :     for (size_t i=0; i<N; i++) {
     373           0 :         if (str[i] == replaceThis) {
     374           0 :             if (!edit) {
     375           0 :                 SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
     376           0 :                 if (!buf) {
     377           0 :                     return NO_MEMORY;
     378             :                 }
     379           0 :                 edit = (char16_t*)buf->data();
     380           0 :                 mString = str = edit;
     381             :             }
     382           0 :             edit[i] = withThis;
     383             :         }
     384             :     }
     385           0 :     return NO_ERROR;
     386             : }
     387             : 
     388           0 : status_t String16::remove(size_t len, size_t begin)
     389             : {
     390           0 :     const size_t N = size();
     391           0 :     if (begin >= N) {
     392           0 :         SharedBuffer::bufferFromData(mString)->release();
     393           0 :         mString = getEmptyString();
     394           0 :         return NO_ERROR;
     395             :     }
     396           0 :     if ((begin+len) > N) len = N-begin;
     397           0 :     if (begin == 0 && len == N) {
     398           0 :         return NO_ERROR;
     399             :     }
     400             : 
     401           0 :     if (begin > 0) {
     402           0 :         SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
     403           0 :             ->editResize((N+1)*sizeof(char16_t));
     404           0 :         if (!buf) {
     405           0 :             return NO_MEMORY;
     406             :         }
     407           0 :         char16_t* str = (char16_t*)buf->data();
     408           0 :         memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
     409           0 :         mString = str;
     410             :     }
     411           0 :     SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
     412           0 :         ->editResize((len+1)*sizeof(char16_t));
     413           0 :     if (buf) {
     414           0 :         char16_t* str = (char16_t*)buf->data();
     415           0 :         str[len] = 0;
     416           0 :         mString = str;
     417           0 :         return NO_ERROR;
     418             :     }
     419           0 :     return NO_MEMORY;
     420             : }
     421             : 
     422             : }; // namespace stagefright

Generated by: LCOV version 1.13