initial import
[vuplus_webkit] / Source / WebKit2 / UIProcess / Launcher / mac / EnvironmentVariables.cpp
1 /*
2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "EnvironmentVariables.h"
28
29 #include <crt_externs.h>
30
31 namespace WebKit {
32
33 EnvironmentVariables::EnvironmentVariables()
34     : m_environmentPointer(*_NSGetEnviron())
35 {
36 }
37
38 EnvironmentVariables::~EnvironmentVariables()
39 {
40     size_t size = m_allocatedStrings.size();
41     for (size_t i = 0; i < size; ++i)
42         fastFree(m_allocatedStrings[i]);
43 }
44
45 void EnvironmentVariables::set(const char* name, const char* value)
46 {
47     // Check if we need to copy the environment.
48     if (m_environmentPointer == *_NSGetEnviron())
49         copyEnvironmentVariables();
50
51     // Allocate a string for the name and value.
52     const char* nameAndValue = createStringForVariable(name, value);
53
54     for (size_t i = 0; i < m_environmentVariables.size() - 1; ++i) {
55         if (valueIfVariableHasName(m_environmentVariables[i], name)) {
56             // Just replace the environment variable.
57             m_environmentVariables[i] = const_cast<char*>(nameAndValue);
58             return;
59         }
60     }
61
62     // Append the new string.
63     ASSERT(!m_environmentVariables.last());
64     m_environmentVariables.last() = const_cast<char*>(nameAndValue);
65     m_environmentVariables.append(static_cast<char*>(0));
66
67     m_environmentPointer = m_environmentVariables.data();
68 }
69
70 const char* EnvironmentVariables::get(const char* name) const
71 {
72     for (size_t i = 0; m_environmentPointer[i]; ++i) {
73         if (const char* value = valueIfVariableHasName(m_environmentPointer[i], name))
74             return value;
75     }
76     return 0;
77 }
78
79 void EnvironmentVariables::appendValue(const char* name, const char* value, char separator)
80 {
81     const char* existingValue = get(name);
82     if (!existingValue) {
83         set(name, value);
84         return;
85     }
86
87     Vector<char, 128> newValue;
88     newValue.append(existingValue, strlen(existingValue));
89     newValue.append(separator);
90     newValue.append(value, strlen(value) + 1);
91
92     set(name, newValue.data());
93 }
94
95 const char* EnvironmentVariables::valueIfVariableHasName(const char* environmentVariable, const char* name) const
96 {
97     // Find the environment variable name.
98     const char* equalsLocation = strchr(environmentVariable, '=');
99     ASSERT(equalsLocation);
100
101     size_t nameLength = equalsLocation - environmentVariable;
102     if (strlen(name) != nameLength)
103         return 0;
104     if (memcmp(environmentVariable, name, nameLength))
105         return 0;
106
107     return equalsLocation + 1;
108 }
109
110 const char* EnvironmentVariables::createStringForVariable(const char* name, const char* value)
111 {
112     int nameLength = strlen(name);
113     int valueLength = strlen(value);
114
115     // Allocate enough room to hold 'name=value' and the null character.
116     char* string = static_cast<char*>(fastMalloc(nameLength + 1 + valueLength + 1));
117     memcpy(string, name, nameLength);
118     string[nameLength] = '=';
119     memcpy(string + nameLength + 1, value, valueLength);
120     string[nameLength + 1 + valueLength] = '\0';
121
122     m_allocatedStrings.append(string);
123
124     return string;
125 }
126
127 void EnvironmentVariables::copyEnvironmentVariables()
128 {
129     for (size_t i = 0; (*_NSGetEnviron())[i]; i++)
130         m_environmentVariables.append((*_NSGetEnviron())[i]);
131
132     // Null-terminate the array.
133     m_environmentVariables.append(static_cast<char*>(0));
134
135     // Update the environment pointer.
136     m_environmentPointer = m_environmentVariables.data();
137 }
138
139 } // namespace WebKit