2011-07-28 14:26:00 +00:00
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
/*
|
2011-07-28 14:26:00 +00:00
|
|
|
* Copyright 2006 The Android Open Source Project
|
2008-12-17 15:59:43 +00:00
|
|
|
*
|
2011-07-28 14:26:00 +00:00
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
2008-12-17 15:59:43 +00:00
|
|
|
*/
|
|
|
|
|
2011-07-28 14:26:00 +00:00
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#ifndef SkString_DEFINED
|
|
|
|
#define SkString_DEFINED
|
|
|
|
|
|
|
|
#include "SkScalar.h"
|
2013-12-02 13:50:38 +00:00
|
|
|
#include "SkTArray.h"
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2013-03-07 18:05:08 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
/* Some helper functions for C strings
|
|
|
|
*/
|
|
|
|
|
2012-10-29 16:42:11 +00:00
|
|
|
static bool SkStrStartsWith(const char string[], const char prefixStr[]) {
|
2012-04-27 17:11:31 +00:00
|
|
|
SkASSERT(string);
|
2012-10-29 16:42:11 +00:00
|
|
|
SkASSERT(prefixStr);
|
|
|
|
return !strncmp(string, prefixStr, strlen(prefixStr));
|
2012-04-27 17:11:31 +00:00
|
|
|
}
|
2012-10-29 16:42:11 +00:00
|
|
|
static bool SkStrStartsWith(const char string[], const char prefixChar) {
|
|
|
|
SkASSERT(string);
|
|
|
|
return (prefixChar == *string);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SkStrEndsWith(const char string[], const char suffixStr[]);
|
|
|
|
bool SkStrEndsWith(const char string[], const char suffixChar);
|
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
|
2012-10-29 16:42:11 +00:00
|
|
|
|
2013-01-14 18:49:19 +00:00
|
|
|
static int SkStrFind(const char string[], const char substring[]) {
|
2013-01-14 19:03:46 +00:00
|
|
|
const char *first = strstr(string, substring);
|
2013-01-14 18:49:19 +00:00
|
|
|
if (NULL == first) return -1;
|
2013-02-04 22:40:28 +00:00
|
|
|
return SkToS32(first - &string[0]);
|
2013-01-14 18:49:19 +00:00
|
|
|
}
|
|
|
|
|
2015-08-13 13:51:35 +00:00
|
|
|
static int SkStrFindLastOf(const char string[], const char subchar) {
|
|
|
|
const char* last = strrchr(string, subchar);
|
|
|
|
if (NULL == last) return -1;
|
|
|
|
return SkToS32(last - &string[0]);
|
|
|
|
}
|
|
|
|
|
2012-04-27 17:11:31 +00:00
|
|
|
static bool SkStrContains(const char string[], const char substring[]) {
|
|
|
|
SkASSERT(string);
|
|
|
|
SkASSERT(substring);
|
2013-01-14 18:49:19 +00:00
|
|
|
return (-1 != SkStrFind(string, substring));
|
2012-04-27 17:11:31 +00:00
|
|
|
}
|
2012-10-29 16:42:11 +00:00
|
|
|
static bool SkStrContains(const char string[], const char subchar) {
|
|
|
|
SkASSERT(string);
|
2013-01-14 18:49:19 +00:00
|
|
|
char tmp[2];
|
|
|
|
tmp[0] = subchar;
|
|
|
|
tmp[1] = '\0';
|
|
|
|
return (-1 != SkStrFind(string, tmp));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline char *SkStrDup(const char string[]) {
|
|
|
|
char *ret = (char *) sk_malloc_throw(strlen(string)+1);
|
2013-03-04 20:03:44 +00:00
|
|
|
memcpy(ret,string,strlen(string)+1);
|
2013-01-14 18:49:19 +00:00
|
|
|
return ret;
|
2012-10-29 16:42:11 +00:00
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2014-11-07 15:37:33 +00:00
|
|
|
/*
|
|
|
|
* The SkStrAppend... methods will write into the provided buffer, assuming it is large enough.
|
|
|
|
* Each method has an associated const (e.g. SkStrAppendU32_MaxSize) which will be the largest
|
|
|
|
* value needed for that method's buffer.
|
|
|
|
*
|
|
|
|
* char storage[SkStrAppendU32_MaxSize];
|
|
|
|
* SkStrAppendU32(storage, value);
|
|
|
|
*
|
|
|
|
* Note : none of the SkStrAppend... methods write a terminating 0 to their buffers. Instead,
|
|
|
|
* the methods return the ptr to the end of the written part of the buffer. This can be used
|
|
|
|
* to compute the length, and/or know where to write a 0 if that is desired.
|
|
|
|
*
|
|
|
|
* char storage[SkStrAppendU32_MaxSize + 1];
|
|
|
|
* char* stop = SkStrAppendU32(storage, value);
|
|
|
|
* size_t len = stop - storage;
|
|
|
|
* *stop = 0; // valid, since storage was 1 byte larger than the max.
|
|
|
|
*/
|
2013-01-14 18:49:19 +00:00
|
|
|
|
2013-06-19 18:27:20 +00:00
|
|
|
#define SkStrAppendU32_MaxSize 10
|
2013-06-19 18:52:42 +00:00
|
|
|
char* SkStrAppendU32(char buffer[], uint32_t);
|
2013-06-19 18:27:20 +00:00
|
|
|
#define SkStrAppendU64_MaxSize 20
|
2013-06-19 18:52:42 +00:00
|
|
|
char* SkStrAppendU64(char buffer[], uint64_t, int minDigits);
|
2013-06-19 18:27:20 +00:00
|
|
|
|
|
|
|
#define SkStrAppendS32_MaxSize (SkStrAppendU32_MaxSize + 1)
|
2008-12-17 15:59:43 +00:00
|
|
|
char* SkStrAppendS32(char buffer[], int32_t);
|
2013-06-19 18:27:20 +00:00
|
|
|
#define SkStrAppendS64_MaxSize (SkStrAppendU64_MaxSize + 1)
|
2010-10-12 23:08:13 +00:00
|
|
|
char* SkStrAppendS64(char buffer[], int64_t, int minDigits);
|
2011-03-01 15:44:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Floats have at most 8 significant digits, so we limit our %g to that.
|
2011-03-03 18:43:14 +00:00
|
|
|
* However, the total string could be 15 characters: -1.2345678e-005
|
|
|
|
*
|
|
|
|
* In theory we should only expect up to 2 digits for the exponent, but on
|
|
|
|
* some platforms we have seen 3 (as in the example above).
|
2011-03-01 15:44:08 +00:00
|
|
|
*/
|
2011-03-03 18:43:14 +00:00
|
|
|
#define SkStrAppendScalar_MaxSize 15
|
2011-03-01 15:44:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Write the scaler in decimal format into buffer, and return a pointer to
|
|
|
|
* the next char after the last one written. Note: a terminating 0 is not
|
|
|
|
* written into buffer, which must be at least SkStrAppendScalar_MaxSize.
|
|
|
|
* Thus if the caller wants to add a 0 at the end, buffer must be at least
|
|
|
|
* SkStrAppendScalar_MaxSize + 1 bytes large.
|
|
|
|
*/
|
2013-12-17 16:44:46 +00:00
|
|
|
#define SkStrAppendScalar SkStrAppendFloat
|
2011-03-03 18:20:12 +00:00
|
|
|
|
|
|
|
char* SkStrAppendFloat(char buffer[], float);
|
|
|
|
char* SkStrAppendFixed(char buffer[], SkFixed);
|
2008-12-17 15:59:43 +00:00
|
|
|
|
|
|
|
/** \class SkString
|
|
|
|
|
|
|
|
Light weight class for managing strings. Uses reference
|
|
|
|
counting to make string assignments and copies very fast
|
|
|
|
with no extra RAM cost. Assumes UTF8 encoding.
|
|
|
|
*/
|
2012-10-18 23:26:44 +00:00
|
|
|
class SK_API SkString {
|
2008-12-17 15:59:43 +00:00
|
|
|
public:
|
|
|
|
SkString();
|
|
|
|
explicit SkString(size_t len);
|
|
|
|
explicit SkString(const char text[]);
|
|
|
|
SkString(const char text[], size_t len);
|
2009-06-21 00:49:18 +00:00
|
|
|
SkString(const SkString&);
|
2008-12-17 15:59:43 +00:00
|
|
|
~SkString();
|
|
|
|
|
2011-09-14 16:13:58 +00:00
|
|
|
bool isEmpty() const { return 0 == fRec->fLength; }
|
2008-12-17 15:59:43 +00:00
|
|
|
size_t size() const { return (size_t) fRec->fLength; }
|
|
|
|
const char* c_str() const { return fRec->data(); }
|
2009-06-21 00:49:18 +00:00
|
|
|
char operator[](size_t n) const { return this->c_str()[n]; }
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2011-04-10 01:04:37 +00:00
|
|
|
bool equals(const SkString&) const;
|
|
|
|
bool equals(const char text[]) const;
|
|
|
|
bool equals(const char text[], size_t len) const;
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2012-10-29 16:42:11 +00:00
|
|
|
bool startsWith(const char prefixStr[]) const {
|
|
|
|
return SkStrStartsWith(fRec->data(), prefixStr);
|
|
|
|
}
|
|
|
|
bool startsWith(const char prefixChar) const {
|
|
|
|
return SkStrStartsWith(fRec->data(), prefixChar);
|
2008-12-17 15:59:43 +00:00
|
|
|
}
|
2012-10-29 16:42:11 +00:00
|
|
|
bool endsWith(const char suffixStr[]) const {
|
|
|
|
return SkStrEndsWith(fRec->data(), suffixStr);
|
|
|
|
}
|
|
|
|
bool endsWith(const char suffixChar) const {
|
|
|
|
return SkStrEndsWith(fRec->data(), suffixChar);
|
2008-12-17 15:59:43 +00:00
|
|
|
}
|
2012-04-27 17:11:31 +00:00
|
|
|
bool contains(const char substring[]) const {
|
|
|
|
return SkStrContains(fRec->data(), substring);
|
|
|
|
}
|
2012-10-29 16:42:11 +00:00
|
|
|
bool contains(const char subchar) const {
|
|
|
|
return SkStrContains(fRec->data(), subchar);
|
|
|
|
}
|
2013-01-14 18:49:19 +00:00
|
|
|
int find(const char substring[]) const {
|
|
|
|
return SkStrFind(fRec->data(), substring);
|
|
|
|
}
|
2015-08-13 13:51:35 +00:00
|
|
|
int findLastOf(const char subchar) const {
|
|
|
|
return SkStrFindLastOf(fRec->data(), subchar);
|
|
|
|
}
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2011-07-20 19:55:42 +00:00
|
|
|
friend bool operator==(const SkString& a, const SkString& b) {
|
2008-12-17 15:59:43 +00:00
|
|
|
return a.equals(b);
|
|
|
|
}
|
2011-07-20 19:55:42 +00:00
|
|
|
friend bool operator!=(const SkString& a, const SkString& b) {
|
2008-12-17 15:59:43 +00:00
|
|
|
return !a.equals(b);
|
|
|
|
}
|
|
|
|
|
|
|
|
// these methods edit the string
|
|
|
|
|
2011-07-20 19:55:42 +00:00
|
|
|
SkString& operator=(const SkString&);
|
|
|
|
SkString& operator=(const char text[]);
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2011-07-20 19:55:42 +00:00
|
|
|
char* writable_str();
|
2009-06-21 00:49:18 +00:00
|
|
|
char& operator[](size_t n) { return this->writable_str()[n]; }
|
2008-12-17 15:59:43 +00:00
|
|
|
|
2011-04-10 01:04:37 +00:00
|
|
|
void reset();
|
2015-08-31 21:36:48 +00:00
|
|
|
/** Destructive resize, does not preserve contents. */
|
2011-04-10 01:04:37 +00:00
|
|
|
void resize(size_t len) { this->set(NULL, len); }
|
|
|
|
void set(const SkString& src) { *this = src; }
|
|
|
|
void set(const char text[]);
|
|
|
|
void set(const char text[], size_t len);
|
|
|
|
void setUTF16(const uint16_t[]);
|
|
|
|
void setUTF16(const uint16_t[], size_t len);
|
|
|
|
|
|
|
|
void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
|
|
|
|
void insert(size_t offset, const char text[]);
|
|
|
|
void insert(size_t offset, const char text[], size_t len);
|
|
|
|
void insertUnichar(size_t offset, SkUnichar);
|
|
|
|
void insertS32(size_t offset, int32_t value);
|
|
|
|
void insertS64(size_t offset, int64_t value, int minDigits = 0);
|
2013-06-19 18:27:20 +00:00
|
|
|
void insertU32(size_t offset, uint32_t value);
|
|
|
|
void insertU64(size_t offset, uint64_t value, int minDigits = 0);
|
2011-04-10 01:04:37 +00:00
|
|
|
void insertHex(size_t offset, uint32_t value, int minDigits = 0);
|
|
|
|
void insertScalar(size_t offset, SkScalar);
|
|
|
|
|
|
|
|
void append(const SkString& str) { this->insert((size_t)-1, str); }
|
|
|
|
void append(const char text[]) { this->insert((size_t)-1, text); }
|
|
|
|
void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
|
|
|
|
void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
|
|
|
|
void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
|
|
|
|
void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
|
2013-06-19 18:27:20 +00:00
|
|
|
void appendU32(uint32_t value) { this->insertU32((size_t)-1, value); }
|
|
|
|
void appendU64(uint64_t value, int minDigits = 0) { this->insertU64((size_t)-1, value, minDigits); }
|
2011-04-10 01:04:37 +00:00
|
|
|
void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
|
|
|
|
void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
|
|
|
|
|
|
|
|
void prepend(const SkString& str) { this->insert(0, str); }
|
|
|
|
void prepend(const char text[]) { this->insert(0, text); }
|
|
|
|
void prepend(const char text[], size_t len) { this->insert(0, text, len); }
|
|
|
|
void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
|
|
|
|
void prependS32(int32_t value) { this->insertS32(0, value); }
|
|
|
|
void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
|
|
|
|
void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
|
|
|
|
void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
|
|
|
|
|
2012-07-09 18:22:08 +00:00
|
|
|
void printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
|
|
|
void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
2013-11-21 17:20:17 +00:00
|
|
|
void appendVAList(const char format[], va_list);
|
2012-07-09 18:22:08 +00:00
|
|
|
void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
2014-08-22 03:18:45 +00:00
|
|
|
void prependVAList(const char format[], va_list);
|
2011-04-10 01:04:37 +00:00
|
|
|
|
|
|
|
void remove(size_t offset, size_t length);
|
|
|
|
|
2011-05-06 13:53:47 +00:00
|
|
|
SkString& operator+=(const SkString& s) { this->append(s); return *this; }
|
|
|
|
SkString& operator+=(const char text[]) { this->append(text); return *this; }
|
2013-05-09 20:01:26 +00:00
|
|
|
SkString& operator+=(const char c) { this->append(&c, 1); return *this; }
|
2011-05-06 13:53:47 +00:00
|
|
|
|
2011-04-10 01:04:37 +00:00
|
|
|
/**
|
|
|
|
* Swap contents between this and other. This function is guaranteed
|
|
|
|
* to never fail or throw.
|
|
|
|
*/
|
|
|
|
void swap(SkString& other);
|
2011-03-01 15:44:08 +00:00
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
private:
|
|
|
|
struct Rec {
|
|
|
|
public:
|
2013-06-04 20:36:52 +00:00
|
|
|
uint32_t fLength; // logically size_t, but we want it to stay 32bits
|
2011-09-14 16:13:58 +00:00
|
|
|
int32_t fRefCnt;
|
2008-12-17 15:59:43 +00:00
|
|
|
char fBeginningOfData;
|
|
|
|
|
|
|
|
char* data() { return &fBeginningOfData; }
|
|
|
|
const char* data() const { return &fBeginningOfData; }
|
|
|
|
};
|
|
|
|
Rec* fRec;
|
|
|
|
|
|
|
|
#ifdef SK_DEBUG
|
|
|
|
void validate() const;
|
|
|
|
#else
|
|
|
|
void validate() const {}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static const Rec gEmptyRec;
|
2011-09-14 16:13:58 +00:00
|
|
|
static Rec* AllocRec(const char text[], size_t len);
|
2008-12-17 15:59:43 +00:00
|
|
|
static Rec* RefRec(Rec*);
|
|
|
|
};
|
|
|
|
|
2011-06-30 14:39:52 +00:00
|
|
|
/// Creates a new string and writes into it using a printf()-style format.
|
|
|
|
SkString SkStringPrintf(const char* format, ...);
|
|
|
|
|
2013-02-27 19:07:32 +00:00
|
|
|
// Specialized to take advantage of SkString's fast swap path. The unspecialized function is
|
|
|
|
// declared in SkTypes.h and called by SkTSort.
|
|
|
|
template <> inline void SkTSwap(SkString& a, SkString& b) {
|
|
|
|
a.swap(b);
|
|
|
|
}
|
|
|
|
|
2013-12-02 13:50:38 +00:00
|
|
|
// Split str on any characters in delimiters into out. (Think, strtok with a sane API.)
|
Revert of Add config options to run different GPU APIs to dm and nanobench (patchset #21 id:400001 of https://codereview.chromium.org/1490113005/ )
Reason for revert:
The Test-Win8-MSVC-ShuttleB-GPU-HD4600-x86_64-Debug builder fails after this CL.
Links to specific builds:
http://build.chromium.org/p/client.skia/builders/Test-Win8-MSVC-ShuttleB-GPU-HD4600-x86_64-Debug/builds/1689
http://build.chromium.org/p/client.skia/builders/Test-Win8-MSVC-ShuttleB-GPU-HD4600-x86_64-Debug/builds/1690
http://build.chromium.org/p/client.skia/builders/Test-Win8-MSVC-ShuttleB-GPU-HD4600-x86_64-Debug/builds/1691
Original issue's description:
> Add config options to run different GPU APIs to dm and nanobench
>
> Add extended config specification form that can be used to run different
> gpu backend with different APIs.
>
> The configs can be specified with the form:
> gpu(api=string,dit=bool,nvpr=bool,samples=int)
>
> This replaces and removes the --gpuAPI flag.
>
> All existing configs should still work.
>
> Adds following documentation:
>
> out/Debug/dm --help config
>
> Flags:
> --config: type: string default: 565 8888 gpu nonrendering
> Options: 565 8888 debug gpu gpudebug gpudft gpunull msaa16 msaa4
> nonrendering null nullgpu nvprmsaa16 nvprmsaa4 pdf pdf_poppler skp svg
> xps or use extended form 'backend(option=value,...)'.
>
> Extended form: 'backend(option=value,...)'
>
> Possible backends and options:
>
> gpu(api=string,dit=bool,nvpr=bool,samples=int) GPU backend
> api type: string default: native.
> Select graphics API to use with gpu backend.
> Options:
> native Use platform default OpenGL or OpenGL ES backend.
> gl Use OpenGL.
> gles Use OpenGL ES.
> debug Use debug OpenGL.
> null Use null OpenGL.
> dit type: bool default: false.
> Use device independent text.
> nvpr type: bool default: false.
> Use NV_path_rendering OpenGL and OpenGL ES extension.
> samples type: int default: 0.
> Use multisampling with N samples.
>
> Predefined configs:
>
> gpu = gpu()
> msaa4 = gpu(samples=4)
> msaa16 = gpu(samples=16)
> nvprmsaa4 = gpu(nvpr=true,samples=4)
> nvprmsaa16 = gpu(nvpr=true,samples=16)
> gpudft = gpu(dit=true)
> gpudebug = gpu(api=debug)
> gpunull = gpu(api=null)
> debug = gpu(api=debug)
> nullgpu = gpu(api=null)
>
> BUG=skia:2992
>
> Committed: https://skia.googlesource.com/skia/+/e13ca329fca4c28cf4e078561f591ab27b743d23
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1490113005
>
> Committed: https://skia.googlesource.com/skia/+/c8b4336444e7b90382e04e33665fb3b8490b825b
>
> Committed: https://skia.googlesource.com/skia/+/9ebc3f0ee6db215dde461dc4777d85988cf272dd
TBR=mtklein@google.com,bsalomon@google.com,joshualitt@google.com,scroggo@google.com,kkinnunen@nvidia.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:2992
Review URL: https://codereview.chromium.org/1548683002
2015-12-22 18:22:26 +00:00
|
|
|
void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out);
|
2013-12-02 13:50:38 +00:00
|
|
|
|
2008-12-17 15:59:43 +00:00
|
|
|
#endif
|