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