security manager conflict commented

Dependencies:   BLE_API mbed-dev-bin nRF51822

Fork of microbit-dal by Lancaster University

Committer:
Jonathan Austin
Date:
Thu Apr 07 01:33:22 2016 +0100
Revision:
1:8aa5cdb4ab67
Child:
51:9198e7bb83dc
Synchronized with git rev 55cb9199

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Class definition for a ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 28 *
Jonathan Austin 1:8aa5cdb4ab67 29 * Uses basic reference counting to implement a copy-assignable, immutable string.
Jonathan Austin 1:8aa5cdb4ab67 30 *
Jonathan Austin 1:8aa5cdb4ab67 31 * This maps closely to the constructs found in many high level application languages,
Jonathan Austin 1:8aa5cdb4ab67 32 * such as Touch Develop.
Jonathan Austin 1:8aa5cdb4ab67 33 *
Jonathan Austin 1:8aa5cdb4ab67 34 * Written from first principles here, for several reasons:
Jonathan Austin 1:8aa5cdb4ab67 35 * 1) std::shared_ptr is not yet availiable on the ARMCC compiler
Jonathan Austin 1:8aa5cdb4ab67 36 *
Jonathan Austin 1:8aa5cdb4ab67 37 * 2) to reduce memory footprint - we don't need many of the other features in the std library
Jonathan Austin 1:8aa5cdb4ab67 38 *
Jonathan Austin 1:8aa5cdb4ab67 39 * 3) it makes an interesting case study for anyone interested in seeing how it works!
Jonathan Austin 1:8aa5cdb4ab67 40 *
Jonathan Austin 1:8aa5cdb4ab67 41 * 4) we need explicit reference counting to inter-op with low-level application langauge runtimes.
Jonathan Austin 1:8aa5cdb4ab67 42 *
Jonathan Austin 1:8aa5cdb4ab67 43 * 5) the reference counting needs to also work for read-only, flash-resident strings
Jonathan Austin 1:8aa5cdb4ab67 44 */
Jonathan Austin 1:8aa5cdb4ab67 45 #include <string.h>
Jonathan Austin 1:8aa5cdb4ab67 46 #include <stdlib.h>
Jonathan Austin 1:8aa5cdb4ab67 47
Jonathan Austin 1:8aa5cdb4ab67 48 #include "mbed.h"
Jonathan Austin 1:8aa5cdb4ab67 49 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 50 #include "ManagedString.h"
Jonathan Austin 1:8aa5cdb4ab67 51 #include "MicroBitCompat.h"
Jonathan Austin 1:8aa5cdb4ab67 52
Jonathan Austin 1:8aa5cdb4ab67 53 static const char empty[] __attribute__ ((aligned (4))) = "\xff\xff\0\0\0";
Jonathan Austin 1:8aa5cdb4ab67 54
Jonathan Austin 1:8aa5cdb4ab67 55 /**
Jonathan Austin 1:8aa5cdb4ab67 56 * Internal constructor helper.
Jonathan Austin 1:8aa5cdb4ab67 57 *
Jonathan Austin 1:8aa5cdb4ab67 58 * Configures this ManagedString to refer to the static EmptyString
Jonathan Austin 1:8aa5cdb4ab67 59 */
Jonathan Austin 1:8aa5cdb4ab67 60 void ManagedString::initEmpty()
Jonathan Austin 1:8aa5cdb4ab67 61 {
Jonathan Austin 1:8aa5cdb4ab67 62 ptr = (StringData*)(void*)empty;
Jonathan Austin 1:8aa5cdb4ab67 63 }
Jonathan Austin 1:8aa5cdb4ab67 64
Jonathan Austin 1:8aa5cdb4ab67 65 /**
Jonathan Austin 1:8aa5cdb4ab67 66 * Internal constructor helper.
Jonathan Austin 1:8aa5cdb4ab67 67 *
Jonathan Austin 1:8aa5cdb4ab67 68 * Creates this ManagedString based on a given null terminated char array.
Jonathan Austin 1:8aa5cdb4ab67 69 */
Jonathan Austin 1:8aa5cdb4ab67 70 void ManagedString::initString(const char *str)
Jonathan Austin 1:8aa5cdb4ab67 71 {
Jonathan Austin 1:8aa5cdb4ab67 72 // Initialise this ManagedString as a new string, using the data provided.
Jonathan Austin 1:8aa5cdb4ab67 73 // We assume the string is sane, and null terminated.
Jonathan Austin 1:8aa5cdb4ab67 74 int len = strlen(str);
Jonathan Austin 1:8aa5cdb4ab67 75 ptr = (StringData *) malloc(4+len+1);
Jonathan Austin 1:8aa5cdb4ab67 76 ptr->init();
Jonathan Austin 1:8aa5cdb4ab67 77 ptr->len = len;
Jonathan Austin 1:8aa5cdb4ab67 78 memcpy(ptr->data, str, len+1);
Jonathan Austin 1:8aa5cdb4ab67 79 }
Jonathan Austin 1:8aa5cdb4ab67 80
Jonathan Austin 1:8aa5cdb4ab67 81 /**
Jonathan Austin 1:8aa5cdb4ab67 82 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 83 * Create a managed string from a specially prepared string literal.
Jonathan Austin 1:8aa5cdb4ab67 84 *
Jonathan Austin 1:8aa5cdb4ab67 85 * @param ptr The literal - first two bytes should be 0xff, then the length in little endian, then the literal. The literal has to be 4-byte aligned.
Jonathan Austin 1:8aa5cdb4ab67 86 *
Jonathan Austin 1:8aa5cdb4ab67 87 * @code
Jonathan Austin 1:8aa5cdb4ab67 88 * static const char hello[] __attribute__ ((aligned (4))) = "\xff\xff\x05\x00" "Hello";
Jonathan Austin 1:8aa5cdb4ab67 89 * ManagedString s((StringData*)(void*)hello);
Jonathan Austin 1:8aa5cdb4ab67 90 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 91 */
Jonathan Austin 1:8aa5cdb4ab67 92 ManagedString::ManagedString(StringData *p)
Jonathan Austin 1:8aa5cdb4ab67 93 {
Jonathan Austin 1:8aa5cdb4ab67 94 ptr = p;
Jonathan Austin 1:8aa5cdb4ab67 95 ptr->incr();
Jonathan Austin 1:8aa5cdb4ab67 96 }
Jonathan Austin 1:8aa5cdb4ab67 97
Jonathan Austin 1:8aa5cdb4ab67 98 /**
Jonathan Austin 1:8aa5cdb4ab67 99 * Get current ptr, do not decr() it, and set the current instance to empty string.
Jonathan Austin 1:8aa5cdb4ab67 100 *
Jonathan Austin 1:8aa5cdb4ab67 101 * This is to be used by specialized runtimes which pass StringData around.
Jonathan Austin 1:8aa5cdb4ab67 102 */
Jonathan Austin 1:8aa5cdb4ab67 103 StringData* ManagedString::leakData()
Jonathan Austin 1:8aa5cdb4ab67 104 {
Jonathan Austin 1:8aa5cdb4ab67 105 StringData *res = ptr;
Jonathan Austin 1:8aa5cdb4ab67 106 initEmpty();
Jonathan Austin 1:8aa5cdb4ab67 107 return res;
Jonathan Austin 1:8aa5cdb4ab67 108 }
Jonathan Austin 1:8aa5cdb4ab67 109
Jonathan Austin 1:8aa5cdb4ab67 110 /**
Jonathan Austin 1:8aa5cdb4ab67 111 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 112 *
Jonathan Austin 1:8aa5cdb4ab67 113 * Create a managed string from a given integer.
Jonathan Austin 1:8aa5cdb4ab67 114 *
Jonathan Austin 1:8aa5cdb4ab67 115 * @param value The integer from which to create the ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 116 *
Jonathan Austin 1:8aa5cdb4ab67 117 * @code
Jonathan Austin 1:8aa5cdb4ab67 118 * ManagedString s(20);
Jonathan Austin 1:8aa5cdb4ab67 119 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 120 */
Jonathan Austin 1:8aa5cdb4ab67 121 ManagedString::ManagedString(const int value)
Jonathan Austin 1:8aa5cdb4ab67 122 {
Jonathan Austin 1:8aa5cdb4ab67 123 char str[12];
Jonathan Austin 1:8aa5cdb4ab67 124
Jonathan Austin 1:8aa5cdb4ab67 125 itoa(value, str);
Jonathan Austin 1:8aa5cdb4ab67 126 initString(str);
Jonathan Austin 1:8aa5cdb4ab67 127 }
Jonathan Austin 1:8aa5cdb4ab67 128
Jonathan Austin 1:8aa5cdb4ab67 129 /**
Jonathan Austin 1:8aa5cdb4ab67 130 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 131 * Create a managed string from a given char.
Jonathan Austin 1:8aa5cdb4ab67 132 *
Jonathan Austin 1:8aa5cdb4ab67 133 * @param value The character from which to create the ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 134 *
Jonathan Austin 1:8aa5cdb4ab67 135 * @code
Jonathan Austin 1:8aa5cdb4ab67 136 * ManagedString s('a');
Jonathan Austin 1:8aa5cdb4ab67 137 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 138 */
Jonathan Austin 1:8aa5cdb4ab67 139 ManagedString::ManagedString(const char value)
Jonathan Austin 1:8aa5cdb4ab67 140 {
Jonathan Austin 1:8aa5cdb4ab67 141 char str[2] = {value, 0};
Jonathan Austin 1:8aa5cdb4ab67 142 initString(str);
Jonathan Austin 1:8aa5cdb4ab67 143 }
Jonathan Austin 1:8aa5cdb4ab67 144
Jonathan Austin 1:8aa5cdb4ab67 145
Jonathan Austin 1:8aa5cdb4ab67 146 /**
Jonathan Austin 1:8aa5cdb4ab67 147 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 148 *
Jonathan Austin 1:8aa5cdb4ab67 149 * Create a managed string from a pointer to an 8-bit character buffer.
Jonathan Austin 1:8aa5cdb4ab67 150 *
Jonathan Austin 1:8aa5cdb4ab67 151 * The buffer is copied to ensure safe memory management (the supplied
Jonathan Austin 1:8aa5cdb4ab67 152 * character buffer may be declared on the stack for instance).
Jonathan Austin 1:8aa5cdb4ab67 153 *
Jonathan Austin 1:8aa5cdb4ab67 154 * @param str The character array on which to base the new ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 155 *
Jonathan Austin 1:8aa5cdb4ab67 156 * @code
Jonathan Austin 1:8aa5cdb4ab67 157 * ManagedString s("abcdefg");
Jonathan Austin 1:8aa5cdb4ab67 158 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 159 */
Jonathan Austin 1:8aa5cdb4ab67 160 ManagedString::ManagedString(const char *str)
Jonathan Austin 1:8aa5cdb4ab67 161 {
Jonathan Austin 1:8aa5cdb4ab67 162 // Sanity check. Return EmptyString for anything distasteful
Jonathan Austin 1:8aa5cdb4ab67 163 if (str == NULL || *str == 0)
Jonathan Austin 1:8aa5cdb4ab67 164 {
Jonathan Austin 1:8aa5cdb4ab67 165 initEmpty();
Jonathan Austin 1:8aa5cdb4ab67 166 return;
Jonathan Austin 1:8aa5cdb4ab67 167 }
Jonathan Austin 1:8aa5cdb4ab67 168
Jonathan Austin 1:8aa5cdb4ab67 169 initString(str);
Jonathan Austin 1:8aa5cdb4ab67 170 }
Jonathan Austin 1:8aa5cdb4ab67 171
Jonathan Austin 1:8aa5cdb4ab67 172 /**
Jonathan Austin 1:8aa5cdb4ab67 173 * Private Constructor.
Jonathan Austin 1:8aa5cdb4ab67 174 *
Jonathan Austin 1:8aa5cdb4ab67 175 * Create a managed string based on a concat of two strings.
Jonathan Austin 1:8aa5cdb4ab67 176 * The buffer is copied to ensure sane memory management (the supplied
Jonathan Austin 1:8aa5cdb4ab67 177 * character buffer may be declared on the stack for instance).
Jonathan Austin 1:8aa5cdb4ab67 178 *
Jonathan Austin 1:8aa5cdb4ab67 179 * @param str1 The first string on which to base the new ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 180 *
Jonathan Austin 1:8aa5cdb4ab67 181 * @param str2 The second string on which to base the new ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 182 */
Jonathan Austin 1:8aa5cdb4ab67 183 ManagedString::ManagedString(const ManagedString &s1, const ManagedString &s2)
Jonathan Austin 1:8aa5cdb4ab67 184 {
Jonathan Austin 1:8aa5cdb4ab67 185 // Calculate length of new string.
Jonathan Austin 1:8aa5cdb4ab67 186 int len = s1.length() + s2.length();
Jonathan Austin 1:8aa5cdb4ab67 187
Jonathan Austin 1:8aa5cdb4ab67 188 // Create a new buffer for holding the new string data.
Jonathan Austin 1:8aa5cdb4ab67 189 ptr = (StringData*) malloc(4+len+1);
Jonathan Austin 1:8aa5cdb4ab67 190 ptr->init();
Jonathan Austin 1:8aa5cdb4ab67 191 ptr->len = len;
Jonathan Austin 1:8aa5cdb4ab67 192
Jonathan Austin 1:8aa5cdb4ab67 193 // Enter the data, and terminate the string.
Jonathan Austin 1:8aa5cdb4ab67 194 memcpy(ptr->data, s1.toCharArray(), s1.length());
Jonathan Austin 1:8aa5cdb4ab67 195 memcpy(ptr->data + s1.length(), s2.toCharArray(), s2.length());
Jonathan Austin 1:8aa5cdb4ab67 196 ptr->data[len] = 0;
Jonathan Austin 1:8aa5cdb4ab67 197 }
Jonathan Austin 1:8aa5cdb4ab67 198
Jonathan Austin 1:8aa5cdb4ab67 199
Jonathan Austin 1:8aa5cdb4ab67 200 /**
Jonathan Austin 1:8aa5cdb4ab67 201 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 202 * Create a ManagedString from a PacketBuffer. All bytes in the
Jonathan Austin 1:8aa5cdb4ab67 203 * PacketBuffer are added to the ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 204 *
Jonathan Austin 1:8aa5cdb4ab67 205 * @param buffer The PacktBuffer from which to create the ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 206 *
Jonathan Austin 1:8aa5cdb4ab67 207 * @code
Jonathan Austin 1:8aa5cdb4ab67 208 * ManagedString s = radio.datagram.recv();
Jonathan Austin 1:8aa5cdb4ab67 209 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 210 */
Jonathan Austin 1:8aa5cdb4ab67 211 ManagedString::ManagedString(PacketBuffer buffer)
Jonathan Austin 1:8aa5cdb4ab67 212 {
Jonathan Austin 1:8aa5cdb4ab67 213 // Allocate a new buffer ( just in case the data is not NULL terminated).
Jonathan Austin 1:8aa5cdb4ab67 214 ptr = (StringData*) malloc(4+buffer.length()+1);
Jonathan Austin 1:8aa5cdb4ab67 215 ptr->init();
Jonathan Austin 1:8aa5cdb4ab67 216
Jonathan Austin 1:8aa5cdb4ab67 217 // Store the length of the new string
Jonathan Austin 1:8aa5cdb4ab67 218 ptr->len = buffer.length();
Jonathan Austin 1:8aa5cdb4ab67 219 memcpy(ptr->data, buffer.getBytes(), buffer.length());
Jonathan Austin 1:8aa5cdb4ab67 220 ptr->data[buffer.length()] = 0;
Jonathan Austin 1:8aa5cdb4ab67 221 }
Jonathan Austin 1:8aa5cdb4ab67 222
Jonathan Austin 1:8aa5cdb4ab67 223 /**
Jonathan Austin 1:8aa5cdb4ab67 224 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 225 * Create a ManagedString from a pointer to an 8-bit character buffer of a given length.
Jonathan Austin 1:8aa5cdb4ab67 226 *
Jonathan Austin 1:8aa5cdb4ab67 227 * The buffer is copied to ensure sane memory management (the supplied
Jonathan Austin 1:8aa5cdb4ab67 228 * character buffer may be declared on the stack for instance).
Jonathan Austin 1:8aa5cdb4ab67 229 *
Jonathan Austin 1:8aa5cdb4ab67 230 * @param str The character array on which to base the new ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 231 *
Jonathan Austin 1:8aa5cdb4ab67 232 * @param length The length of the character array
Jonathan Austin 1:8aa5cdb4ab67 233 *
Jonathan Austin 1:8aa5cdb4ab67 234 * @code
Jonathan Austin 1:8aa5cdb4ab67 235 * ManagedString s("abcdefg",7);
Jonathan Austin 1:8aa5cdb4ab67 236 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 237 */
Jonathan Austin 1:8aa5cdb4ab67 238 ManagedString::ManagedString(const char *str, const int16_t length)
Jonathan Austin 1:8aa5cdb4ab67 239 {
Jonathan Austin 1:8aa5cdb4ab67 240 // Sanity check. Return EmptyString for anything distasteful
Jonathan Austin 1:8aa5cdb4ab67 241 if (str == NULL || *str == 0 || (uint16_t)length > strlen(str)) // XXX length should be unsigned on the interface
Jonathan Austin 1:8aa5cdb4ab67 242 {
Jonathan Austin 1:8aa5cdb4ab67 243 initEmpty();
Jonathan Austin 1:8aa5cdb4ab67 244 return;
Jonathan Austin 1:8aa5cdb4ab67 245 }
Jonathan Austin 1:8aa5cdb4ab67 246
Jonathan Austin 1:8aa5cdb4ab67 247
Jonathan Austin 1:8aa5cdb4ab67 248 // Allocate a new buffer, and create a NULL terminated string.
Jonathan Austin 1:8aa5cdb4ab67 249 ptr = (StringData*) malloc(4+length+1);
Jonathan Austin 1:8aa5cdb4ab67 250 ptr->init();
Jonathan Austin 1:8aa5cdb4ab67 251 // Store the length of the new string
Jonathan Austin 1:8aa5cdb4ab67 252 ptr->len = length;
Jonathan Austin 1:8aa5cdb4ab67 253 memcpy(ptr->data, str, length);
Jonathan Austin 1:8aa5cdb4ab67 254 ptr->data[length] = 0;
Jonathan Austin 1:8aa5cdb4ab67 255 }
Jonathan Austin 1:8aa5cdb4ab67 256
Jonathan Austin 1:8aa5cdb4ab67 257 /**
Jonathan Austin 1:8aa5cdb4ab67 258 * Copy constructor.
Jonathan Austin 1:8aa5cdb4ab67 259 * Makes a new ManagedString identical to the one supplied.
Jonathan Austin 1:8aa5cdb4ab67 260 *
Jonathan Austin 1:8aa5cdb4ab67 261 * Shares the character buffer and reference count with the supplied ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 262 *
Jonathan Austin 1:8aa5cdb4ab67 263 * @param s The ManagedString to copy.
Jonathan Austin 1:8aa5cdb4ab67 264 *
Jonathan Austin 1:8aa5cdb4ab67 265 * @code
Jonathan Austin 1:8aa5cdb4ab67 266 * ManagedString s("abcdefg");
Jonathan Austin 1:8aa5cdb4ab67 267 * ManagedString p(s);
Jonathan Austin 1:8aa5cdb4ab67 268 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 269 */
Jonathan Austin 1:8aa5cdb4ab67 270 ManagedString::ManagedString(const ManagedString &s)
Jonathan Austin 1:8aa5cdb4ab67 271 {
Jonathan Austin 1:8aa5cdb4ab67 272 ptr = s.ptr;
Jonathan Austin 1:8aa5cdb4ab67 273 ptr->incr();
Jonathan Austin 1:8aa5cdb4ab67 274 }
Jonathan Austin 1:8aa5cdb4ab67 275
Jonathan Austin 1:8aa5cdb4ab67 276
Jonathan Austin 1:8aa5cdb4ab67 277 /**
Jonathan Austin 1:8aa5cdb4ab67 278 * Default constructor.
Jonathan Austin 1:8aa5cdb4ab67 279 *
Jonathan Austin 1:8aa5cdb4ab67 280 * Create an empty ManagedString.
Jonathan Austin 1:8aa5cdb4ab67 281 *
Jonathan Austin 1:8aa5cdb4ab67 282 * @code
Jonathan Austin 1:8aa5cdb4ab67 283 * ManagedString s();
Jonathan Austin 1:8aa5cdb4ab67 284 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 285 */
Jonathan Austin 1:8aa5cdb4ab67 286 ManagedString::ManagedString()
Jonathan Austin 1:8aa5cdb4ab67 287 {
Jonathan Austin 1:8aa5cdb4ab67 288 initEmpty();
Jonathan Austin 1:8aa5cdb4ab67 289 }
Jonathan Austin 1:8aa5cdb4ab67 290
Jonathan Austin 1:8aa5cdb4ab67 291 /**
Jonathan Austin 1:8aa5cdb4ab67 292 * Destructor.
Jonathan Austin 1:8aa5cdb4ab67 293 *
Jonathan Austin 1:8aa5cdb4ab67 294 * Free this ManagedString, and decrement the reference count to the
Jonathan Austin 1:8aa5cdb4ab67 295 * internal character buffer.
Jonathan Austin 1:8aa5cdb4ab67 296 *
Jonathan Austin 1:8aa5cdb4ab67 297 * If we're holding the last reference, also free the character buffer.
Jonathan Austin 1:8aa5cdb4ab67 298 */
Jonathan Austin 1:8aa5cdb4ab67 299 ManagedString::~ManagedString()
Jonathan Austin 1:8aa5cdb4ab67 300 {
Jonathan Austin 1:8aa5cdb4ab67 301 ptr->decr();
Jonathan Austin 1:8aa5cdb4ab67 302 }
Jonathan Austin 1:8aa5cdb4ab67 303
Jonathan Austin 1:8aa5cdb4ab67 304 /**
Jonathan Austin 1:8aa5cdb4ab67 305 * Copy assign operation.
Jonathan Austin 1:8aa5cdb4ab67 306 *
Jonathan Austin 1:8aa5cdb4ab67 307 * Called when one ManagedString is assigned the value of another.
Jonathan Austin 1:8aa5cdb4ab67 308 *
Jonathan Austin 1:8aa5cdb4ab67 309 * If the ManagedString being assigned is already refering to a character buffer,
Jonathan Austin 1:8aa5cdb4ab67 310 * decrement the reference count and free up the buffer as necessary.
Jonathan Austin 1:8aa5cdb4ab67 311 *
Jonathan Austin 1:8aa5cdb4ab67 312 * Then, update our character buffer to refer to that of the supplied ManagedString,
Jonathan Austin 1:8aa5cdb4ab67 313 * and increase its reference count.
Jonathan Austin 1:8aa5cdb4ab67 314 *
Jonathan Austin 1:8aa5cdb4ab67 315 * @param s The ManagedString to copy.
Jonathan Austin 1:8aa5cdb4ab67 316 *
Jonathan Austin 1:8aa5cdb4ab67 317 * @code
Jonathan Austin 1:8aa5cdb4ab67 318 * ManagedString s("abcd");
Jonathan Austin 1:8aa5cdb4ab67 319 * ManagedString p("efgh");
Jonathan Austin 1:8aa5cdb4ab67 320 * p = s // p now points to s, s' ref is incremented
Jonathan Austin 1:8aa5cdb4ab67 321 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 322 */
Jonathan Austin 1:8aa5cdb4ab67 323 ManagedString& ManagedString::operator = (const ManagedString& s)
Jonathan Austin 1:8aa5cdb4ab67 324 {
Jonathan Austin 1:8aa5cdb4ab67 325 if (this->ptr == s.ptr)
Jonathan Austin 1:8aa5cdb4ab67 326 return *this;
Jonathan Austin 1:8aa5cdb4ab67 327
Jonathan Austin 1:8aa5cdb4ab67 328 ptr->decr();
Jonathan Austin 1:8aa5cdb4ab67 329 ptr = s.ptr;
Jonathan Austin 1:8aa5cdb4ab67 330 ptr->incr();
Jonathan Austin 1:8aa5cdb4ab67 331
Jonathan Austin 1:8aa5cdb4ab67 332 return *this;
Jonathan Austin 1:8aa5cdb4ab67 333 }
Jonathan Austin 1:8aa5cdb4ab67 334
Jonathan Austin 1:8aa5cdb4ab67 335 /**
Jonathan Austin 1:8aa5cdb4ab67 336 * Equality operation.
Jonathan Austin 1:8aa5cdb4ab67 337 *
Jonathan Austin 1:8aa5cdb4ab67 338 * Called when one ManagedString is tested to be equal to another using the '==' operator.
Jonathan Austin 1:8aa5cdb4ab67 339 *
Jonathan Austin 1:8aa5cdb4ab67 340 * @param s The ManagedString to test ourselves against.
Jonathan Austin 1:8aa5cdb4ab67 341 *
Jonathan Austin 1:8aa5cdb4ab67 342 * @return true if this ManagedString is identical to the one supplied, false otherwise.
Jonathan Austin 1:8aa5cdb4ab67 343 *
Jonathan Austin 1:8aa5cdb4ab67 344 * @code
Jonathan Austin 1:8aa5cdb4ab67 345 * MicroBitDisplay display;
Jonathan Austin 1:8aa5cdb4ab67 346 * ManagedString s("abcd");
Jonathan Austin 1:8aa5cdb4ab67 347 * ManagedString p("efgh");
Jonathan Austin 1:8aa5cdb4ab67 348 *
Jonathan Austin 1:8aa5cdb4ab67 349 * if(p == s)
Jonathan Austin 1:8aa5cdb4ab67 350 * display.scroll("We are the same!");
Jonathan Austin 1:8aa5cdb4ab67 351 * else
Jonathan Austin 1:8aa5cdb4ab67 352 * display.scroll("We are different!"); //p is not equal to s - this will be called
Jonathan Austin 1:8aa5cdb4ab67 353 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 354 */
Jonathan Austin 1:8aa5cdb4ab67 355 bool ManagedString::operator== (const ManagedString& s)
Jonathan Austin 1:8aa5cdb4ab67 356 {
Jonathan Austin 1:8aa5cdb4ab67 357 return ((length() == s.length()) && (strcmp(toCharArray(),s.toCharArray())==0));
Jonathan Austin 1:8aa5cdb4ab67 358 }
Jonathan Austin 1:8aa5cdb4ab67 359
Jonathan Austin 1:8aa5cdb4ab67 360 /**
Jonathan Austin 1:8aa5cdb4ab67 361 * Inequality operation.
Jonathan Austin 1:8aa5cdb4ab67 362 *
Jonathan Austin 1:8aa5cdb4ab67 363 * Called when one ManagedString is tested to be less than another using the '<' operator.
Jonathan Austin 1:8aa5cdb4ab67 364 *
Jonathan Austin 1:8aa5cdb4ab67 365 * @param s The ManagedString to test ourselves against.
Jonathan Austin 1:8aa5cdb4ab67 366 *
Jonathan Austin 1:8aa5cdb4ab67 367 * @return true if this ManagedString is alphabetically less than to the one supplied, false otherwise.
Jonathan Austin 1:8aa5cdb4ab67 368 *
Jonathan Austin 1:8aa5cdb4ab67 369 * @code
Jonathan Austin 1:8aa5cdb4ab67 370 * MicroBitDisplay display;
Jonathan Austin 1:8aa5cdb4ab67 371 * ManagedString s("a");
Jonathan Austin 1:8aa5cdb4ab67 372 * ManagedString p("b");
Jonathan Austin 1:8aa5cdb4ab67 373 *
Jonathan Austin 1:8aa5cdb4ab67 374 * if(s < p)
Jonathan Austin 1:8aa5cdb4ab67 375 * display.scroll("a is before b!"); //a is before b
Jonathan Austin 1:8aa5cdb4ab67 376 * else
Jonathan Austin 1:8aa5cdb4ab67 377 * display.scroll("b is before a!");
Jonathan Austin 1:8aa5cdb4ab67 378 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 379 */
Jonathan Austin 1:8aa5cdb4ab67 380 bool ManagedString::operator< (const ManagedString& s)
Jonathan Austin 1:8aa5cdb4ab67 381 {
Jonathan Austin 1:8aa5cdb4ab67 382 return (strcmp(toCharArray(), s.toCharArray())<0);
Jonathan Austin 1:8aa5cdb4ab67 383 }
Jonathan Austin 1:8aa5cdb4ab67 384
Jonathan Austin 1:8aa5cdb4ab67 385 /**
Jonathan Austin 1:8aa5cdb4ab67 386 * Inequality operation.
Jonathan Austin 1:8aa5cdb4ab67 387 *
Jonathan Austin 1:8aa5cdb4ab67 388 * Called when one ManagedString is tested to be greater than another using the '>' operator.
Jonathan Austin 1:8aa5cdb4ab67 389 *
Jonathan Austin 1:8aa5cdb4ab67 390 * @param s The ManagedString to test ourselves against.
Jonathan Austin 1:8aa5cdb4ab67 391 *
Jonathan Austin 1:8aa5cdb4ab67 392 * @return true if this ManagedString is alphabetically greater than to the one supplied, false otherwise.
Jonathan Austin 1:8aa5cdb4ab67 393 *
Jonathan Austin 1:8aa5cdb4ab67 394 * @code
Jonathan Austin 1:8aa5cdb4ab67 395 * MicroBitDisplay display;
Jonathan Austin 1:8aa5cdb4ab67 396 * ManagedString s("a");
Jonathan Austin 1:8aa5cdb4ab67 397 * ManagedString p("b");
Jonathan Austin 1:8aa5cdb4ab67 398 *
Jonathan Austin 1:8aa5cdb4ab67 399 * if(p>a)
Jonathan Austin 1:8aa5cdb4ab67 400 * display.scroll("b is after a!"); //b is after a
Jonathan Austin 1:8aa5cdb4ab67 401 * else
Jonathan Austin 1:8aa5cdb4ab67 402 * display.scroll("a is after b!");
Jonathan Austin 1:8aa5cdb4ab67 403 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 404 */
Jonathan Austin 1:8aa5cdb4ab67 405 bool ManagedString::operator> (const ManagedString& s)
Jonathan Austin 1:8aa5cdb4ab67 406 {
Jonathan Austin 1:8aa5cdb4ab67 407 return (strcmp(toCharArray(), s.toCharArray())>0);
Jonathan Austin 1:8aa5cdb4ab67 408 }
Jonathan Austin 1:8aa5cdb4ab67 409
Jonathan Austin 1:8aa5cdb4ab67 410 /**
Jonathan Austin 1:8aa5cdb4ab67 411 * Extracts a ManagedString from this string, at the position provided.
Jonathan Austin 1:8aa5cdb4ab67 412 *
Jonathan Austin 1:8aa5cdb4ab67 413 * @param start The index of the first character to extract, indexed from zero.
Jonathan Austin 1:8aa5cdb4ab67 414 *
Jonathan Austin 1:8aa5cdb4ab67 415 * @param length The number of characters to extract from the start position
Jonathan Austin 1:8aa5cdb4ab67 416 *
Jonathan Austin 1:8aa5cdb4ab67 417 * @return a ManagedString representing the requested substring.
Jonathan Austin 1:8aa5cdb4ab67 418 *
Jonathan Austin 1:8aa5cdb4ab67 419 * @code
Jonathan Austin 1:8aa5cdb4ab67 420 * MicroBitDisplay display;
Jonathan Austin 1:8aa5cdb4ab67 421 * ManagedString s("abcdefg");
Jonathan Austin 1:8aa5cdb4ab67 422 *
Jonathan Austin 1:8aa5cdb4ab67 423 * display.scroll(s.substring(0,2)) // displays "ab"
Jonathan Austin 1:8aa5cdb4ab67 424 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 425 */
Jonathan Austin 1:8aa5cdb4ab67 426 ManagedString ManagedString::substring(int16_t start, int16_t length)
Jonathan Austin 1:8aa5cdb4ab67 427 {
Jonathan Austin 1:8aa5cdb4ab67 428 // If the parameters are illegal, just return a reference to the empty string.
Jonathan Austin 1:8aa5cdb4ab67 429 if (start >= this->length())
Jonathan Austin 1:8aa5cdb4ab67 430 return ManagedString(ManagedString::EmptyString);
Jonathan Austin 1:8aa5cdb4ab67 431
Jonathan Austin 1:8aa5cdb4ab67 432 // Compute a safe copy length;
Jonathan Austin 1:8aa5cdb4ab67 433 length = min(this->length()-start, length);
Jonathan Austin 1:8aa5cdb4ab67 434
Jonathan Austin 1:8aa5cdb4ab67 435 // Build a ManagedString from this.
Jonathan Austin 1:8aa5cdb4ab67 436 return ManagedString(toCharArray()+start, length);
Jonathan Austin 1:8aa5cdb4ab67 437 }
Jonathan Austin 1:8aa5cdb4ab67 438
Jonathan Austin 1:8aa5cdb4ab67 439 /**
Jonathan Austin 1:8aa5cdb4ab67 440 * Concatenates this string with the one provided.
Jonathan Austin 1:8aa5cdb4ab67 441 *
Jonathan Austin 1:8aa5cdb4ab67 442 * @param s The ManagedString to concatenate.
Jonathan Austin 1:8aa5cdb4ab67 443 *
Jonathan Austin 1:8aa5cdb4ab67 444 * @return a new ManagedString representing the joined strings.
Jonathan Austin 1:8aa5cdb4ab67 445 *
Jonathan Austin 1:8aa5cdb4ab67 446 * @code
Jonathan Austin 1:8aa5cdb4ab67 447 * MicroBitDisplay display;
Jonathan Austin 1:8aa5cdb4ab67 448 * ManagedString s("abcd");
Jonathan Austin 1:8aa5cdb4ab67 449 * ManagedString p("efgh")
Jonathan Austin 1:8aa5cdb4ab67 450 *
Jonathan Austin 1:8aa5cdb4ab67 451 * display.scroll(s + p) // scrolls "abcdefgh"
Jonathan Austin 1:8aa5cdb4ab67 452 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 453 */
Jonathan Austin 1:8aa5cdb4ab67 454 ManagedString ManagedString::operator+ (ManagedString& s)
Jonathan Austin 1:8aa5cdb4ab67 455 {
Jonathan Austin 1:8aa5cdb4ab67 456 // If the other string is empty, nothing to do!
Jonathan Austin 1:8aa5cdb4ab67 457 if(s.length() == 0)
Jonathan Austin 1:8aa5cdb4ab67 458 return *this;
Jonathan Austin 1:8aa5cdb4ab67 459
Jonathan Austin 1:8aa5cdb4ab67 460 if (length() == 0)
Jonathan Austin 1:8aa5cdb4ab67 461 return s;
Jonathan Austin 1:8aa5cdb4ab67 462
Jonathan Austin 1:8aa5cdb4ab67 463 return ManagedString(*this, s);
Jonathan Austin 1:8aa5cdb4ab67 464 }
Jonathan Austin 1:8aa5cdb4ab67 465
Jonathan Austin 1:8aa5cdb4ab67 466
Jonathan Austin 1:8aa5cdb4ab67 467 /**
Jonathan Austin 1:8aa5cdb4ab67 468 * Provides a character value at a given position in the string, indexed from zero.
Jonathan Austin 1:8aa5cdb4ab67 469 *
Jonathan Austin 1:8aa5cdb4ab67 470 * @param index The position of the character to return.
Jonathan Austin 1:8aa5cdb4ab67 471 *
Jonathan Austin 1:8aa5cdb4ab67 472 * @return the character at posisiton index, zero if index is invalid.
Jonathan Austin 1:8aa5cdb4ab67 473 *
Jonathan Austin 1:8aa5cdb4ab67 474 * @code
Jonathan Austin 1:8aa5cdb4ab67 475 * MicroBitDisplay display;
Jonathan Austin 1:8aa5cdb4ab67 476 * ManagedString s("abcd");
Jonathan Austin 1:8aa5cdb4ab67 477 *
Jonathan Austin 1:8aa5cdb4ab67 478 * display.scroll(s.charAt(1)) // scrolls "b"
Jonathan Austin 1:8aa5cdb4ab67 479 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 480 */
Jonathan Austin 1:8aa5cdb4ab67 481 char ManagedString::charAt(int16_t index)
Jonathan Austin 1:8aa5cdb4ab67 482 {
Jonathan Austin 1:8aa5cdb4ab67 483 return (index >=0 && index < length()) ? ptr->data[index] : 0;
Jonathan Austin 1:8aa5cdb4ab67 484 }
Jonathan Austin 1:8aa5cdb4ab67 485
Jonathan Austin 1:8aa5cdb4ab67 486 /**
Jonathan Austin 1:8aa5cdb4ab67 487 * Empty string constant literal
Jonathan Austin 1:8aa5cdb4ab67 488 */
Jonathan Austin 1:8aa5cdb4ab67 489 ManagedString ManagedString::EmptyString((StringData*)(void*)empty);