1/*-
2 * Copyright (c) 2013 David Chisnall
3 * All rights reserved.
4 *
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7 * ("CTSRD"), as part of the DARPA CRASH research programme.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33#ifndef _STRING_HH_
34#define _STRING_HH_
35#include "input_buffer.hh"
36
37namespace dtc
38{
39
40/**
41 * String, referring to a place in the input file.  We don't bother copying
42 * strings until we write them to the final output.  These strings should be
43 * two words long: a start and a length.  They are intended to be cheap to copy
44 * and store in collections.  Copying the string object does not copy the
45 * underlying storage.
46 *
47 * Strings are not nul-terminated.
48 */
49class string
50{
51	/** Start address.  Contained within the mmap()'d input file and not
52	 * owned by this object. */
53	const char *start;
54	/** length of the string.  DTS strings are allowed to contain nuls */
55	int length;
56	/** Generic function for parsing strings matching the character set
57	 * defined by the template argument.  */
58	template<class T>
59	static string parse(input_buffer &s);
60	public:
61	/**
62	 * Constructs a string referring into another buffer.
63	 */
64	string(const char *s, int l) : start(s), length(l) {}
65	/** Constructs a string from a C string.  */
66	string(const char *s) : start(s), length(strlen(s)) {}
67	/** Default constructor, returns an empty string. */
68	string() : start(0), length(0) {}
69	/** Construct a from an input buffer, ending with a nul terminator. */
70	string(input_buffer &s);
71	/**
72	 * Returns the longest string in the input buffer starting at the
73	 * current cursor and composed entirely of characters that are valid in
74	 * node names.
75	 */
76	static string parse_node_name(input_buffer &s);
77	/**
78	 * Returns the longest string in the input buffer starting at the
79	 * current cursor and composed entirely of characters that are valid in
80	 * property names.
81	 */
82	static string parse_property_name(input_buffer &s);
83	/**
84	 * Parses either a node or a property name.  If is_property is true on
85	 * entry, then only property names are parsed.  If it is false, then it
86	 * will be set, on return, to indicate whether the parsed name is only
87	 * valid as a property.
88	 */
89	static string parse_node_or_property_name(input_buffer &s,
90	                                          bool &is_property);
91	/**
92	 * Compares two strings for equality.  Strings are equal if they refer
93	 * to identical byte sequences.
94	 */
95	bool operator==(const string& other) const;
96	/**
97	 * Compares a string against a C string.  The trailing nul in the C
98	 * string is ignored for the purpose of comparison, so this will always
99	 * fail if the string contains nul bytes.
100	 */
101	bool operator==(const char *other) const;
102	/**
103	 * Inequality operator, defined as the inverse of the equality
104	 * operator.
105	 */
106	template <typename T>
107	inline bool operator!=(T other)
108	{
109		return !(*this == other);
110	}
111	/**
112	 * Comparison operator, defined to allow strings to be used as keys in
113	 * maps.
114	 */
115	bool operator<(const string& other) const;
116	/**
117	 * Returns true if this is the empty string, false otherwise.
118	 */
119	inline bool empty() const
120	{
121		return length == 0;
122	}
123	/**
124	 * Returns the size of the string, in bytes.
125	 */
126	inline size_t size()
127	{
128		return length;
129	}
130	/**
131	 * Writes the string to the specified buffer.
132	 */
133	void push_to_buffer(byte_buffer &buffer, bool escapes=false);
134	/**
135	 * Prints the string to the specified output stream.
136	 */
137	void print(FILE *file);
138	/**
139	 * Dumps the string to the standard error stream.  Intended to be used
140	 * for debugging.
141	 */
142	void dump();
143};
144
145} // namespace dtc
146
147#endif // !_STRING_HH_
148