1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "crazy_linker_util.h"
6 
7 #include <stdio.h>
8 
9 namespace crazy {
10 
11 // Return the base name from a file path. Important: this is a pointer
12 // into the original string.
13 // static
GetBaseNamePtr(const char * path)14 const char* GetBaseNamePtr(const char* path) {
15   const char* p = strrchr(path, '/');
16   if (!p)
17     return path;
18   else
19     return p + 1;
20 }
21 
22 // static
23 const char String::kEmpty[] = "";
24 
String()25 String::String() { Init(); }
26 
String(const String & other)27 String::String(const String& other) {
28   Init();
29   Assign(other.ptr_, other.size_);
30 }
31 
String(const char * str)32 String::String(const char* str) {
33   Init();
34   Assign(str, strlen(str));
35 }
36 
String(char ch)37 String::String(char ch) {
38   Init();
39   Assign(&ch, 1);
40 }
41 
~String()42 String::~String() {
43   if (ptr_ != const_cast<char*>(kEmpty)) {
44     free(ptr_);
45     ptr_ = const_cast<char*>(kEmpty);
46   }
47 }
48 
String(const char * str,size_t len)49 String::String(const char* str, size_t len) {
50   Init();
51   Assign(str, len);
52 }
53 
Assign(const char * str,size_t len)54 void String::Assign(const char* str, size_t len) {
55   Resize(len);
56   if (len > 0) {
57     memcpy(ptr_, str, len);
58     ptr_[len] = '\0';
59     size_ = len;
60   }
61 }
62 
Append(const char * str,size_t len)63 void String::Append(const char* str, size_t len) {
64   if (len > 0) {
65     size_t old_size = size_;
66     Resize(size_ + len);
67     memcpy(ptr_ + old_size, str, len);
68   }
69 }
70 
Resize(size_t new_size)71 void String::Resize(size_t new_size) {
72   if (new_size > capacity_) {
73     size_t new_capacity = capacity_;
74     while (new_capacity < new_size) {
75       new_capacity += (new_capacity >> 1) + 16;
76     }
77     Reserve(new_capacity);
78   }
79 
80   if (new_size > size_)
81     memset(ptr_ + size_, '\0', new_size - size_);
82 
83   size_ = new_size;
84   if (ptr_ != kEmpty)
85     ptr_[size_] = '\0';
86 }
87 
Reserve(size_t new_capacity)88 void String::Reserve(size_t new_capacity) {
89   char* old_ptr = (ptr_ == const_cast<char*>(kEmpty)) ? NULL : ptr_;
90   // Always allocate one more byte for the trailing \0
91   ptr_ = reinterpret_cast<char*>(realloc(old_ptr, new_capacity + 1));
92   ptr_[new_capacity] = '\0';
93   capacity_ = new_capacity;
94 
95   if (size_ > new_capacity)
96     size_ = new_capacity;
97 }
98 
99 #if 0
100 String Format(const char* fmt, ...) {
101   va_list args;
102   va_start(args, fmt);
103   String result(FormatArgs(fmt, args));
104   va_end(args);
105   return result;
106 }
107 
108 String FormatArgs(const char* fmt, va_list args) {
109   String result;
110   for (;;) {
111     va_list args2;
112     va_copy(args2, args);
113     int ret = vsnprintf(&result[0], result.capacity(), fmt, args2);
114     va_end(args2);
115     if (static_cast<size_t>(ret) <= result.capacity())
116       break;
117 
118     result.Resize(static_cast<size_t>(ret));
119   }
120   return result;
121 }
122 #endif
123 
124 }  // namespace crazy
125