1245803Stheraven/*-
2245803Stheraven * Copyright (c) 2013 David Chisnall
3245803Stheraven * All rights reserved.
4245803Stheraven *
5245803Stheraven * This software was developed by SRI International and the University of
6245803Stheraven * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7245803Stheraven * ("CTSRD"), as part of the DARPA CRASH research programme.
8245803Stheraven *
9245803Stheraven * Redistribution and use in source and binary forms, with or without
10245803Stheraven * modification, are permitted provided that the following conditions
11245803Stheraven * are met:
12245803Stheraven * 1. Redistributions of source code must retain the above copyright
13245803Stheraven *    notice, this list of conditions and the following disclaimer.
14245803Stheraven * 2. Redistributions in binary form must reproduce the above copyright
15245803Stheraven *    notice, this list of conditions and the following disclaimer in the
16245803Stheraven *    documentation and/or other materials provided with the distribution.
17245803Stheraven *
18245803Stheraven * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19245803Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20245803Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21245803Stheraven * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22245803Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23245803Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24245803Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25245803Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26245803Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27245803Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28245803Stheraven * SUCH DAMAGE.
29245803Stheraven *
30245803Stheraven * $FreeBSD$
31245803Stheraven */
32245803Stheraven
33245803Stheraven#ifndef _STRING_HH_
34245803Stheraven#define _STRING_HH_
35245803Stheraven#include "input_buffer.hh"
36245803Stheraven
37245803Stheravennamespace dtc
38245803Stheraven{
39245803Stheraven
40245803Stheraven/**
41245803Stheraven * String, referring to a place in the input file.  We don't bother copying
42245803Stheraven * strings until we write them to the final output.  These strings should be
43245803Stheraven * two words long: a start and a length.  They are intended to be cheap to copy
44245803Stheraven * and store in collections.  Copying the string object does not copy the
45245803Stheraven * underlying storage.
46245803Stheraven *
47245803Stheraven * Strings are not nul-terminated.
48245803Stheraven */
49245803Stheravenclass string
50245803Stheraven{
51245803Stheraven	/** Start address.  Contained within the mmap()'d input file and not
52245803Stheraven	 * owned by this object. */
53245803Stheraven	const char *start;
54245803Stheraven	/** length of the string.  DTS strings are allowed to contain nuls */
55245803Stheraven	int length;
56245803Stheraven	/** Generic function for parsing strings matching the character set
57245803Stheraven	 * defined by the template argument.  */
58245803Stheraven	template<class T>
59245803Stheraven	static string parse(input_buffer &s);
60245803Stheraven	public:
61245803Stheraven	/**
62245803Stheraven	 * Constructs a string referring into another buffer.
63245803Stheraven	 */
64245803Stheraven	string(const char *s, int l) : start(s), length(l) {}
65245803Stheraven	/** Constructs a string from a C string.  */
66245803Stheraven	string(const char *s) : start(s), length(strlen(s)) {}
67245803Stheraven	/** Default constructor, returns an empty string. */
68245803Stheraven	string() : start(0), length(0) {}
69245803Stheraven	/** Construct a from an input buffer, ending with a nul terminator. */
70245803Stheraven	string(input_buffer &s);
71245803Stheraven	/**
72245803Stheraven	 * Returns the longest string in the input buffer starting at the
73245803Stheraven	 * current cursor and composed entirely of characters that are valid in
74245803Stheraven	 * node names.
75245803Stheraven	 */
76245803Stheraven	static string parse_node_name(input_buffer &s);
77245803Stheraven	/**
78245803Stheraven	 * Returns the longest string in the input buffer starting at the
79245803Stheraven	 * current cursor and composed entirely of characters that are valid in
80245803Stheraven	 * property names.
81245803Stheraven	 */
82245803Stheraven	static string parse_property_name(input_buffer &s);
83245803Stheraven	/**
84245803Stheraven	 * Parses either a node or a property name.  If is_property is true on
85245803Stheraven	 * entry, then only property names are parsed.  If it is false, then it
86245803Stheraven	 * will be set, on return, to indicate whether the parsed name is only
87245803Stheraven	 * valid as a property.
88245803Stheraven	 */
89245803Stheraven	static string parse_node_or_property_name(input_buffer &s,
90245803Stheraven	                                          bool &is_property);
91245803Stheraven	/**
92245803Stheraven	 * Compares two strings for equality.  Strings are equal if they refer
93245803Stheraven	 * to identical byte sequences.
94245803Stheraven	 */
95245803Stheraven	bool operator==(const string& other) const;
96245803Stheraven	/**
97245803Stheraven	 * Compares a string against a C string.  The trailing nul in the C
98245803Stheraven	 * string is ignored for the purpose of comparison, so this will always
99245803Stheraven	 * fail if the string contains nul bytes.
100245803Stheraven	 */
101245803Stheraven	bool operator==(const char *other) const;
102245803Stheraven	/**
103245803Stheraven	 * Inequality operator, defined as the inverse of the equality
104245803Stheraven	 * operator.
105245803Stheraven	 */
106245803Stheraven	template <typename T>
107245803Stheraven	inline bool operator!=(T other)
108245803Stheraven	{
109245803Stheraven		return !(*this == other);
110245803Stheraven	}
111245803Stheraven	/**
112245803Stheraven	 * Comparison operator, defined to allow strings to be used as keys in
113245803Stheraven	 * maps.
114245803Stheraven	 */
115245803Stheraven	bool operator<(const string& other) const;
116245803Stheraven	/**
117245803Stheraven	 * Returns true if this is the empty string, false otherwise.
118245803Stheraven	 */
119245803Stheraven	inline bool empty() const
120245803Stheraven	{
121245803Stheraven		return length == 0;
122245803Stheraven	}
123245803Stheraven	/**
124245803Stheraven	 * Returns the size of the string, in bytes.
125245803Stheraven	 */
126245803Stheraven	inline size_t size()
127245803Stheraven	{
128245803Stheraven		return length;
129245803Stheraven	}
130245803Stheraven	/**
131245803Stheraven	 * Writes the string to the specified buffer.
132245803Stheraven	 */
133245803Stheraven	void push_to_buffer(byte_buffer &buffer, bool escapes=false);
134245803Stheraven	/**
135245803Stheraven	 * Prints the string to the specified output stream.
136245803Stheraven	 */
137245803Stheraven	void print(FILE *file);
138245803Stheraven	/**
139245803Stheraven	 * Dumps the string to the standard error stream.  Intended to be used
140245803Stheraven	 * for debugging.
141245803Stheraven	 */
142245803Stheraven	void dump();
143245803Stheraven};
144245803Stheraven
145245803Stheraven} // namespace dtc
146245803Stheraven
147245803Stheraven#endif // !_STRING_HH_
148