1c55a96383497a772a307b346368133960b02ad03Eric Laurent/*
2c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3c55a96383497a772a307b346368133960b02ad03Eric Laurent *
4c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Use of this source code is governed by a BSD-style license
5c55a96383497a772a307b346368133960b02ad03Eric Laurent *  that can be found in the LICENSE file in the root of the source
6c55a96383497a772a307b346368133960b02ad03Eric Laurent *  tree. An additional intellectual property rights grant can be found
7c55a96383497a772a307b346368133960b02ad03Eric Laurent *  in the file PATENTS.  All contributing project authors may
8c55a96383497a772a307b346368133960b02ad03Eric Laurent *  be found in the AUTHORS file in the root of the source tree.
9c55a96383497a772a307b346368133960b02ad03Eric Laurent */
10c55a96383497a772a307b346368133960b02ad03Eric Laurent
11c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "testsupport/fileutils.h"
12c55a96383497a772a307b346368133960b02ad03Eric Laurent
13c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WIN32
14c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <direct.h>
15c55a96383497a772a307b346368133960b02ad03Eric Laurent#define GET_CURRENT_DIR _getcwd
16c55a96383497a772a307b346368133960b02ad03Eric Laurent#else
17c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <unistd.h>
18c55a96383497a772a307b346368133960b02ad03Eric Laurent#define GET_CURRENT_DIR getcwd
19c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif
20c55a96383497a772a307b346368133960b02ad03Eric Laurent
21c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <sys/stat.h>  // To check for directory existence.
22c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifndef S_ISDIR  // Not defined in stat.h on Windows.
23c55a96383497a772a307b346368133960b02ad03Eric Laurent#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
24c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif
25c55a96383497a772a307b346368133960b02ad03Eric Laurent
26c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <cstdio>
27c55a96383497a772a307b346368133960b02ad03Eric Laurent
28c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "typedefs.h"  // For architecture defines
29c55a96383497a772a307b346368133960b02ad03Eric Laurent
30c55a96383497a772a307b346368133960b02ad03Eric Laurentnamespace webrtc {
31c55a96383497a772a307b346368133960b02ad03Eric Laurentnamespace test {
32c55a96383497a772a307b346368133960b02ad03Eric Laurent
33c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WIN32
34c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const char* kPathDelimiter = "\\";
35c55a96383497a772a307b346368133960b02ad03Eric Laurent#else
36c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const char* kPathDelimiter = "/";
37c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif
38c55a96383497a772a307b346368133960b02ad03Eric Laurent// The file we're looking for to identify the project root dir.
39c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const char* kProjectRootFileName = "DEPS";
40c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const char* kOutputDirName = "out";
41c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const char* kFallbackPath = "./";
42c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const char* kResourcesDirName = "resources";
43c55a96383497a772a307b346368133960b02ad03Eric Laurentconst char* kCannotFindProjectRootDir = "ERROR_CANNOT_FIND_PROJECT_ROOT_DIR";
44c55a96383497a772a307b346368133960b02ad03Eric Laurent
45c55a96383497a772a307b346368133960b02ad03Eric Laurentstd::string ProjectRootPath() {
46c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::string working_dir = WorkingDir();
47c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (working_dir == kFallbackPath) {
48c55a96383497a772a307b346368133960b02ad03Eric Laurent    return kCannotFindProjectRootDir;
49c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
50c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Check for our file that verifies the root dir.
51c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::string current_path(working_dir);
52c55a96383497a772a307b346368133960b02ad03Eric Laurent  FILE* file = NULL;
53c55a96383497a772a307b346368133960b02ad03Eric Laurent  int path_delimiter_index = current_path.find_last_of(kPathDelimiter);
54c55a96383497a772a307b346368133960b02ad03Eric Laurent  while (path_delimiter_index > -1) {
55c55a96383497a772a307b346368133960b02ad03Eric Laurent    std::string root_filename = current_path + kPathDelimiter +
56c55a96383497a772a307b346368133960b02ad03Eric Laurent        kProjectRootFileName;
57c55a96383497a772a307b346368133960b02ad03Eric Laurent    file = fopen(root_filename.c_str(), "r");
58c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (file != NULL) {
59c55a96383497a772a307b346368133960b02ad03Eric Laurent      fclose(file);
60c55a96383497a772a307b346368133960b02ad03Eric Laurent      return current_path + kPathDelimiter;
61c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
62c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Move up one directory in the directory tree.
63c55a96383497a772a307b346368133960b02ad03Eric Laurent    current_path = current_path.substr(0, path_delimiter_index);
64c55a96383497a772a307b346368133960b02ad03Eric Laurent    path_delimiter_index = current_path.find_last_of(kPathDelimiter);
65c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
66c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Reached the root directory.
67c55a96383497a772a307b346368133960b02ad03Eric Laurent  fprintf(stderr, "Cannot find project root directory!\n");
68c55a96383497a772a307b346368133960b02ad03Eric Laurent  return kCannotFindProjectRootDir;
69c55a96383497a772a307b346368133960b02ad03Eric Laurent}
70c55a96383497a772a307b346368133960b02ad03Eric Laurent
71c55a96383497a772a307b346368133960b02ad03Eric Laurentstd::string OutputPath() {
72c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::string path = ProjectRootPath();
73c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (path == kCannotFindProjectRootDir) {
74c55a96383497a772a307b346368133960b02ad03Eric Laurent    return kFallbackPath;
75c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
76c55a96383497a772a307b346368133960b02ad03Eric Laurent  path += kOutputDirName;
77c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!CreateDirectory(path)) {
78c55a96383497a772a307b346368133960b02ad03Eric Laurent    return kFallbackPath;
79c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
80c55a96383497a772a307b346368133960b02ad03Eric Laurent  return path + kPathDelimiter;
81c55a96383497a772a307b346368133960b02ad03Eric Laurent}
82c55a96383497a772a307b346368133960b02ad03Eric Laurent
83c55a96383497a772a307b346368133960b02ad03Eric Laurentstd::string WorkingDir() {
84c55a96383497a772a307b346368133960b02ad03Eric Laurent  char path_buffer[FILENAME_MAX];
85c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!GET_CURRENT_DIR(path_buffer, sizeof(path_buffer))) {
86c55a96383497a772a307b346368133960b02ad03Eric Laurent    fprintf(stderr, "Cannot get current directory!\n");
87c55a96383497a772a307b346368133960b02ad03Eric Laurent    return kFallbackPath;
88c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else {
89c55a96383497a772a307b346368133960b02ad03Eric Laurent    return std::string(path_buffer);
90c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
91c55a96383497a772a307b346368133960b02ad03Eric Laurent}
92c55a96383497a772a307b346368133960b02ad03Eric Laurent
93c55a96383497a772a307b346368133960b02ad03Eric Laurentbool CreateDirectory(std::string directory_name) {
94c55a96383497a772a307b346368133960b02ad03Eric Laurent  struct stat path_info = {0};
95c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Check if the path exists already:
96c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (stat(directory_name.c_str(), &path_info) == 0) {
97c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (!S_ISDIR(path_info.st_mode)) {
98c55a96383497a772a307b346368133960b02ad03Eric Laurent      fprintf(stderr, "Path %s exists but is not a directory! Remove this "
99c55a96383497a772a307b346368133960b02ad03Eric Laurent              "file and re-run to create the directory.\n",
100c55a96383497a772a307b346368133960b02ad03Eric Laurent              directory_name.c_str());
101c55a96383497a772a307b346368133960b02ad03Eric Laurent      return false;
102c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
103c55a96383497a772a307b346368133960b02ad03Eric Laurent  } else {
104c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WIN32
105c55a96383497a772a307b346368133960b02ad03Eric Laurent    return _mkdir(directory_name.c_str()) == 0;
106c55a96383497a772a307b346368133960b02ad03Eric Laurent#else
107c55a96383497a772a307b346368133960b02ad03Eric Laurent    return mkdir(directory_name.c_str(),  S_IRWXU | S_IRWXG | S_IRWXO) == 0;
108c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif
109c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
110c55a96383497a772a307b346368133960b02ad03Eric Laurent  return true;
111c55a96383497a772a307b346368133960b02ad03Eric Laurent}
112c55a96383497a772a307b346368133960b02ad03Eric Laurent
113c55a96383497a772a307b346368133960b02ad03Eric Laurentbool FileExists(std::string file_name) {
114c55a96383497a772a307b346368133960b02ad03Eric Laurent  struct stat file_info = {0};
115c55a96383497a772a307b346368133960b02ad03Eric Laurent  return stat(file_name.c_str(), &file_info) == 0;
116c55a96383497a772a307b346368133960b02ad03Eric Laurent}
117c55a96383497a772a307b346368133960b02ad03Eric Laurent
118c55a96383497a772a307b346368133960b02ad03Eric Laurentstd::string ResourcePath(std::string name, std::string extension) {
119c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::string platform = "win";
120c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_LINUX
121c55a96383497a772a307b346368133960b02ad03Eric Laurent  platform = "linux";
122c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif  // WEBRTC_LINUX
123c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_MAC
124c55a96383497a772a307b346368133960b02ad03Eric Laurent  platform = "mac";
125c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif  // WEBRTC_MAC
126c55a96383497a772a307b346368133960b02ad03Eric Laurent
127c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_ARCH_64_BITS
128c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::string architecture = "64";
129c55a96383497a772a307b346368133960b02ad03Eric Laurent#else
130c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::string architecture = "32";
131c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif  // WEBRTC_ARCH_64_BITS
132c55a96383497a772a307b346368133960b02ad03Eric Laurent
133c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::string resources_path = ProjectRootPath() + kResourcesDirName +
134c55a96383497a772a307b346368133960b02ad03Eric Laurent      kPathDelimiter;
135c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::string resource_file = resources_path + name + "_" + platform + "_" +
136c55a96383497a772a307b346368133960b02ad03Eric Laurent      architecture + "." + extension;
137c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (FileExists(resource_file)) {
138c55a96383497a772a307b346368133960b02ad03Eric Laurent    return resource_file;
139c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
140c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Try without architecture.
141c55a96383497a772a307b346368133960b02ad03Eric Laurent  resource_file = resources_path + name + "_" + platform + "." + extension;
142c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (FileExists(resource_file)) {
143c55a96383497a772a307b346368133960b02ad03Eric Laurent    return resource_file;
144c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
145c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Try without platform.
146c55a96383497a772a307b346368133960b02ad03Eric Laurent  resource_file = resources_path + name + "_" + architecture + "." + extension;
147c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (FileExists(resource_file)) {
148c55a96383497a772a307b346368133960b02ad03Eric Laurent    return resource_file;
149c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
150c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Fall back on name without architecture or platform.
151c55a96383497a772a307b346368133960b02ad03Eric Laurent  return resources_path + name + "." + extension;
152c55a96383497a772a307b346368133960b02ad03Eric Laurent}
153c55a96383497a772a307b346368133960b02ad03Eric Laurent
154c55a96383497a772a307b346368133960b02ad03Eric Laurentsize_t GetFileSize(std::string filename) {
155c55a96383497a772a307b346368133960b02ad03Eric Laurent  FILE* f = fopen(filename.c_str(), "rb");
156c55a96383497a772a307b346368133960b02ad03Eric Laurent  size_t size = 0;
157c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (f != NULL) {
158c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (fseek(f, 0, SEEK_END) == 0) {
159c55a96383497a772a307b346368133960b02ad03Eric Laurent      size = ftell(f);
160c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
161c55a96383497a772a307b346368133960b02ad03Eric Laurent    fclose(f);
162c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
163c55a96383497a772a307b346368133960b02ad03Eric Laurent  return size;
164c55a96383497a772a307b346368133960b02ad03Eric Laurent}
165c55a96383497a772a307b346368133960b02ad03Eric Laurent
166c55a96383497a772a307b346368133960b02ad03Eric Laurent}  // namespace test
167c55a96383497a772a307b346368133960b02ad03Eric Laurent}  // namespace webrtc
168