source: cpp/common/stl-util.cpp @ 317

Last change on this file since 317 was 286, checked in by Maciej Komosinski, 10 years ago

Updated headers

  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "stl-util.h"
6#include <stdarg.h>
7#include <stdlib.h>
8#include "nonstd_stdio.h"
9#include "Convert.h"
10#include "nonstd.h"
11#include "framsg.h"
12#include <assert.h>
13#ifdef USE_VIRTFILE
14#include <frams/virtfile/virtfile.h>
15#endif
16#ifdef __BORLANDC__
17#define va_copy(to,from) to=from //borland does not have va_copy() at all; va_list is just a pointer in borland
18#endif
19
20string ssprintf_va(const char* format, va_list ap)
21{
22        string s; //clang crashed when this declaration was in s=buf
23        long size = 256;
24        char* buf;
25        va_list ap_copy; // "va_list ap" can only by used once by printf-type functions as they advance the current argument pointer (crashed on linux x86_64)
26        // (does not apply to SString::sprintf, it does not have the va_list variant)
27
28        //almost like SString::sprintf, but there is no common code to share because SString can use its directWrite to avoid double allocating/copying
29#ifdef USE_VSCPRINTF
30        va_copy(ap_copy, ap);
31        size = _vscprintf(format, ap_copy) + 1; //+1 for terminating null character
32        va_end(ap_copy);
33#endif
34
35        while (1)
36        {
37                buf = (char*)malloc(size);
38                assert(buf != NULL);
39                va_copy(ap_copy, ap);
40                int n = vsnprintf(buf, size, format, ap_copy);
41                va_end(ap_copy);
42                if (n > -1 && n < size)
43                {
44                        s = buf;
45                        free(buf);
46                        return s;
47                }
48#ifdef VSNPRINTF_RETURNS_REQUIRED_SIZE
49                if (n > -1)    /* glibc 2.1 */
50                        size = n+1; /* precisely what is needed */
51                else           /* glibc 2.0 */
52#endif
53                        size *= 2;  /* twice the old size */
54                free(buf);
55        }
56}
57
58char* strmove(char *a, char *b) //strcpy that works well for overlapping strings ("Source and destination overlap")
59{
60        if (a == NULL || b == NULL)
61                return NULL;
62        memmove(a, b, strlen(b) + 1);
63        return a;
64}
65
66string ssprintf(const char* format, ...)
67{
68        va_list ap;
69        va_start(ap, format);
70        string ret = ssprintf_va(format, ap); //is it too wasteful? copying the string again... unless the compiler can handle it better
71        va_end(ap);
72        return ret;
73}
74
75bool readCompleteFile(const char* filename, vector<char>& data, bool warn_on_missing_file)
76{
77        bool ok = false;
78#ifdef USE_VIRTFILE
79        if (!isAbsolutePath(filename))
80        {
81                VirtFILE *f=Vfopen(filename,FOPEN_READ_BINARY);
82                if (f)
83                {
84                        int size=f->getSize();
85                        data.resize(size);
86                        int przeczytane = f->Vread(&data[0], size, 1);
87                        ok = przeczytane == 1;
88                        delete f;
89                }
90        }
91        else
92#endif
93        {
94#ifdef _WIN32
95                MFILE *f = mfopen(Convert::utf8ToUtf16(filename).c_str(), Convert::strTOwstr(FOPEN_READ_BINARY).c_str());
96#else
97                MFILE *f = mfopen(filename, FOPEN_READ_BINARY);
98#endif
99                if (f)
100                {
101                        int size = getFileSize(f);
102                        data.resize(size);
103                        int przeczytane = mfread(&data[0], size, 1, f);
104                        mfclose(f);
105                        ok = przeczytane == 1;
106                }
107        }
108        if (warn_on_missing_file && !ok)
109                FMprintf("stl-util", "readCompleteFile", FMLV_WARN, "Couldn't open file '%s'", filename);
110        return ok;
111}
112
113bool readCompleteFile(const char* filename, string& out, bool warn_on_missing_file)
114{
115        vector<char> data;
116        if (readCompleteFile(filename, data, warn_on_missing_file))
117        {
118                out = string(&data[0], data.size());
119                return true;
120        }
121        return false;
122}
123
124bool writeCompleteFile(const char* filename, const string& text, bool warn_on_fail)
125{
126#ifdef _WIN32
127        MFILE *f = mfopen(Convert::utf8ToUtf16(filename).c_str(), Convert::strTOwstr(FOPEN_WRITE_BINARY).c_str());
128#else
129        MFILE *f = mfopen(filename, FOPEN_WRITE_BINARY);
130#endif
131        bool ok = f != NULL;
132        if (f)
133        {
134                int zapisane = mfwrite(text.c_str(), text.length(), 1, f);
135                mfclose(f);
136                ok &= zapisane == 1;
137        }
138        if (warn_on_fail && !ok)
139                FMprintf("stl-util", "writeCompleteFile", FMLV_WARN, "couldn't write file '%s'", filename);
140        return ok;
141}
142
143bool writeCompleteFile(const char* filename, vector<char>& data, bool warn_on_fail)
144{
145        string s(&data[0], data.size());
146        return writeCompleteFile(filename, s, warn_on_fail);
147}
148
149
150
151string stripExt(const string& filename)
152{
153        int dot = filename.rfind('.');
154        if (dot == string::npos) return filename;
155        int sep = filename.rfind(PATH_SEPARATOR_CHAR);
156        if ((sep == string::npos) || (sep < dot))
157                return filename.substr(0, dot);
158        return filename;
159}
160
161string getFileExt(const string& filename)
162{
163        int dot = filename.rfind('.');
164        if (dot == string::npos) return string("");
165        int sep = filename.rfind(PATH_SEPARATOR_CHAR);
166        if ((sep == string::npos) || (sep < dot))
167                return filename.substr(dot);
168        return string("");
169}
170
171string getFileDir(const string& filename)
172{
173        int slash = filename.rfind(PATH_SEPARATOR_CHAR);
174        if (slash == string::npos) return string("");
175        return filename.substr(0, slash);
176}
Note: See TracBrowser for help on using the repository browser.