1/* 2 * Copyright 2003, Tyler Dauwalder, tyler@dauwalder.net. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "DString.h" 8 9#include <string.h> 10 11 12/*! \brief Creates a useless, empty string object. */ 13DString::DString() 14 : 15 fLength(0), 16 fString(NULL) 17{ 18} 19 20 21/*! \brief Create a new DString object that is a copy of \a ref. */ 22DString::DString(const DString &ref) 23 : 24 fLength(0), 25 fString(NULL) 26{ 27 SetTo(ref); 28} 29 30 31/*! \brief Creates a new DString \a fieldLength bytes long that contains 32 at most the first \c (fieldLength-1) bytes of \a string.Cs0(). 33*/ 34DString::DString(const UdfString &string, uint8 fieldLength) 35 : 36 fLength(0), 37 fString(NULL) 38{ 39 SetTo(string, fieldLength); 40} 41 42 43/*! \brief Creates a new DString \a fieldLength bytes long that contains 44 at most the first \c (fieldLength-1) bytes of the Cs0 representation 45 of the NULL-terminated UTF8 string \a utf8. 46*/ 47DString::DString(const char *utf8, uint8 fieldLength) 48 : 49 fLength(0), 50 fString(NULL) 51{ 52 SetTo(utf8, fieldLength); 53} 54 55 56DString::~DString() 57{ 58 delete[] fString; 59} 60 61 62void 63DString::SetTo(const DString &ref) 64{ 65 _Clear(); 66 if (ref.Length() > 0) { 67 fString = new(nothrow) uint8[ref.Length()]; 68 if (fString != NULL) { 69 fLength = ref.Length(); 70 memcpy(fString, ref.String(), fLength); 71 } 72 } 73} 74 75 76/*! \brief Sets the DString be \a fieldLength bytes long and contain 77 at most the first \c (fieldLength-1) bytes of \a string.Cs0(). 78*/ 79void 80DString::SetTo(const UdfString &string, uint8 fieldLength) 81{ 82 _Clear(); 83 if (fieldLength > 0) { 84 // Allocate our string 85 fString = new(nothrow) uint8[fieldLength]; 86 status_t error = fString ? B_OK : B_NO_MEMORY; 87 if (!error) { 88 // Figure out how many bytes to copy 89 uint32 sourceLength = string.Cs0Length(); 90 if (sourceLength > 0) { 91 uint8 destLength = sourceLength > uint8(fieldLength - 1) 92 ? uint8(fieldLength - 1) : uint8(sourceLength); 93 // If the source string is 16-bit unicode, make sure any dangling 94 // half-character at the end of the string is not copied 95 if (string.Cs0()[1] == '\x10' && destLength > 0 96 && destLength % 2 == 0) 97 destLength--; 98 // Copy 99 memcpy(fString, string.Cs0(), destLength); 100 // Zero any characters between the end of the string and 101 // the terminating string length character 102 if (destLength < fieldLength - 1) 103 memset(&fString[destLength], 0, fieldLength - 1 - destLength); 104 // Write the string length to the last character in the field 105 fString[fieldLength - 1] = destLength; 106 } else { 107 // Empty strings are to contain all zeros 108 memset(fString, 0, fieldLength); 109 } 110 } 111 } 112} 113 114 115/*! \brief Sets the DString be \a fieldLength bytes long and contain 116 at most the first \c (fieldLength-1) bytes of the Cs0 representation 117 of the NULL-terminated UTF8 string \a utf8. 118*/ 119void 120DString::SetTo(const char *utf8, uint8 fieldLength) 121{ 122 UdfString string(utf8); 123 SetTo(string, fieldLength); 124} 125 126 127void 128DString::_Clear() 129{ 130 DEBUG_INIT("DString"); 131 delete[] fString; 132 fString = NULL; 133 fLength = 0; 134} 135