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 #include <string> 37 #include <functional> 38 39 namespace dtc 40 { 41 42 /** 43 * String, referring to a place in the input file. We don't bother copying 44 * strings until we write them to the final output. These strings should be 45 * two words long: a start and a length. They are intended to be cheap to copy 46 * and store in collections. Copying the string object does not copy the 47 * underlying storage. 48 * 49 * Strings are not nul-terminated. 50 */ 51 class string 52 { 53 friend std::hash<string>; 54 /** Start address. Contained within the mmap()'d input file and not 55 * owned by this object. */ 56 const char *start; 57 /** length of the string. DTS strings are allowed to contain nuls */ 58 int length; 59 /** Generic function for parsing strings matching the character set 60 * defined by the template argument. */ 61 template<class T> 62 static string parse(input_buffer &s); 63 public: 64 /** 65 * Constructs a string referring into another buffer. 66 */ string(const char * s,int l)67 string(const char *s, int l) : start(s), length(l) {} 68 /** Constructs a string from a C string. */ string(const char * s)69 string(const char *s) : start(s), length(strlen(s)) {} 70 /** Default constructor, returns an empty string. */ string()71 string() : start(0), length(0) {} 72 /** Construct a from an input buffer, ending with a nul terminator. */ 73 string(input_buffer &s); 74 /** 75 * Returns the longest string in the input buffer starting at the 76 * current cursor and composed entirely of characters that are valid in 77 * node names. 78 */ 79 static string parse_node_name(input_buffer &s); 80 /** 81 * Returns the longest string in the input buffer starting at the 82 * current cursor and composed entirely of characters that are valid in 83 * property names. 84 */ 85 static string parse_property_name(input_buffer &s); 86 /** 87 * Parses either a node or a property name. If is_property is true on 88 * entry, then only property names are parsed. If it is false, then it 89 * will be set, on return, to indicate whether the parsed name is only 90 * valid as a property. 91 */ 92 static string parse_node_or_property_name(input_buffer &s, 93 bool &is_property); 94 /** 95 * Compares two strings for equality. Strings are equal if they refer 96 * to identical byte sequences. 97 */ 98 bool operator==(const string& other) const; 99 /** 100 * Compares a string against a C string. The trailing nul in the C 101 * string is ignored for the purpose of comparison, so this will always 102 * fail if the string contains nul bytes. 103 */ 104 bool operator==(const char *other) const; 105 /** 106 * Inequality operator, defined as the inverse of the equality 107 * operator. 108 */ 109 template <typename T> operator !=(T other)110 inline bool operator!=(T other) 111 { 112 return !(*this == other); 113 } 114 /** 115 * Comparison operator, defined to allow strings to be used as keys in 116 * maps. 117 */ 118 bool operator<(const string& other) const; 119 /** 120 * Returns true if this is the empty string, false otherwise. 121 */ empty() const122 inline bool empty() const 123 { 124 return length == 0; 125 } 126 /** 127 * Returns the size of the string, in bytes. 128 */ size()129 inline size_t size() 130 { 131 return length; 132 } 133 /** 134 * Writes the string to the specified buffer. 135 */ 136 void push_to_buffer(byte_buffer &buffer, bool escapes=false); 137 /** 138 * Prints the string to the specified output stream. 139 */ 140 void print(FILE *file); 141 /** 142 * Dumps the string to the standard error stream. Intended to be used 143 * for debugging. 144 */ 145 void dump(); 146 }; 147 148 } // namespace dtc 149 namespace std 150 { 151 template<> 152 struct hash<dtc::string> 153 { operator ()std::hash154 std::size_t operator()(dtc::string const& s) const 155 { 156 std::string str(s.start, s.length); 157 std::hash<std::string> h; 158 return h(str); 159 } 160 }; 161 } 162 163 164 #endif // !_STRING_HH_ 165