xref: /haiku/src/add-ons/kernel/file_systems/udf/DString.cpp (revision 71452e98334eaac603bf542d159e24788a46bebb)
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. */
13 DString::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. */
22 DString::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 */
34 DString::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 */
47 DString::DString(const char *utf8, uint8 fieldLength)
48 	:
49 	fLength(0),
50 	fString(NULL)
51 {
52 	SetTo(utf8, fieldLength);
53 }
54 
55 
56 DString::~DString()
57 {
58 	delete[] fString;
59 }
60 
61 
62 void
63 DString::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 */
79 void
80 DString::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 */
119 void
120 DString::SetTo(const char *utf8, uint8 fieldLength)
121 {
122 	UdfString string(utf8);
123 	SetTo(string, fieldLength);
124 }
125 
126 
127 void
128 DString::_Clear()
129 {
130 	DEBUG_INIT("DString");
131 	delete[] fString;
132 	fString = NULL;
133 	fLength = 0;
134 }
135