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

Last change on this file since 247 was 247, checked in by Maciej Komosinski, 8 years ago

Sources support both 32-bit and 64-bit, and more compilers

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