show alpha2 country code strings next to the flag in the country code selectors....
[twcon.git] / src / engine / shared / filecollection.cpp
blob622534f2d411c20043475c71ffca54d5cb7dd85f
1 /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2 /* If you are missing that file, acquire a complete release at teeworlds.com. */
4 #include <base/math.h>
6 #include <engine/storage.h>
8 #include "filecollection.h"
10 bool CFileCollection::IsFilenameValid(const char *pFilename)
12 if(str_length(pFilename) != m_FileDescLength+TIMESTAMP_LENGTH+m_FileExtLength ||
13 str_comp_num(pFilename, m_aFileDesc, m_FileDescLength) ||
14 str_comp(pFilename+m_FileDescLength+TIMESTAMP_LENGTH, m_aFileExt))
15 return false;
17 pFilename += m_FileDescLength;
18 if(pFilename[0] == '_' &&
19 pFilename[1] >= '0' && pFilename[1] <= '9' &&
20 pFilename[2] >= '0' && pFilename[2] <= '9' &&
21 pFilename[3] >= '0' && pFilename[3] <= '9' &&
22 pFilename[4] >= '0' && pFilename[4] <= '9' &&
23 pFilename[5] == '-' &&
24 pFilename[6] >= '0' && pFilename[6] <= '9' &&
25 pFilename[7] >= '0' && pFilename[7] <= '9' &&
26 pFilename[8] == '-' &&
27 pFilename[9] >= '0' && pFilename[9] <= '9' &&
28 pFilename[10] >= '0' && pFilename[10] <= '9' &&
29 pFilename[11] == '_' &&
30 pFilename[12] >= '0' && pFilename[12] <= '9' &&
31 pFilename[13] >= '0' && pFilename[13] <= '9' &&
32 pFilename[14] == '-' &&
33 pFilename[15] >= '0' && pFilename[15] <= '9' &&
34 pFilename[16] >= '0' && pFilename[16] <= '9' &&
35 pFilename[17] == '-' &&
36 pFilename[18] >= '0' && pFilename[18] <= '9' &&
37 pFilename[19] >= '0' && pFilename[19] <= '9')
38 return true;
40 return false;
43 int64 CFileCollection::ExtractTimestamp(const char *pTimestring)
45 int64 Timestamp = pTimestring[0]-'0'; Timestamp <<= 4;
46 Timestamp += pTimestring[1]-'0'; Timestamp <<= 4;
47 Timestamp += pTimestring[2]-'0'; Timestamp <<= 4;
48 Timestamp += pTimestring[3]-'0'; Timestamp <<= 4;
49 Timestamp += pTimestring[5]-'0'; Timestamp <<= 4;
50 Timestamp += pTimestring[6]-'0'; Timestamp <<= 4;
51 Timestamp += pTimestring[8]-'0'; Timestamp <<= 4;
52 Timestamp += pTimestring[9]-'0'; Timestamp <<= 4;
53 Timestamp += pTimestring[11]-'0'; Timestamp <<= 4;
54 Timestamp += pTimestring[12]-'0'; Timestamp <<= 4;
55 Timestamp += pTimestring[14]-'0'; Timestamp <<= 4;
56 Timestamp += pTimestring[15]-'0'; Timestamp <<= 4;
57 Timestamp += pTimestring[17]-'0'; Timestamp <<= 4;
58 Timestamp += pTimestring[18]-'0';
60 return Timestamp;
63 void CFileCollection::BuildTimestring(int64 Timestamp, char *pTimestring)
65 pTimestring[19] = 0;
66 pTimestring[18] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
67 pTimestring[17] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
68 pTimestring[16] = '-';
69 pTimestring[15] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
70 pTimestring[14] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
71 pTimestring[13] = '-';
72 pTimestring[12] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
73 pTimestring[11] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
74 pTimestring[10] = '_';
75 pTimestring[9] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
76 pTimestring[8] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
77 pTimestring[7] = '-';
78 pTimestring[6] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
79 pTimestring[5] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
80 pTimestring[4] = '-';
81 pTimestring[3] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
82 pTimestring[2] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
83 pTimestring[1] = (Timestamp&0xF)+'0'; Timestamp >>= 4;
84 pTimestring[0] = (Timestamp&0xF)+'0';
87 void CFileCollection::Init(IStorage *pStorage, const char *pPath, const char *pFileDesc, const char *pFileExt, int MaxEntries)
89 mem_zero(m_aTimestamps, sizeof(m_aTimestamps));
90 m_NumTimestamps = 0;
91 m_MaxEntries = clamp(MaxEntries, 1, static_cast<int>(MAX_ENTRIES));
92 str_copy(m_aFileDesc, pFileDesc, sizeof(m_aFileDesc));
93 m_FileDescLength = str_length(m_aFileDesc);
94 str_copy(m_aFileExt, pFileExt, sizeof(m_aFileExt));
95 m_FileExtLength = str_length(m_aFileExt);
96 str_copy(m_aPath, pPath, sizeof(m_aPath));
97 m_pStorage = pStorage;
99 m_pStorage->ListDirectory(IStorage::TYPE_SAVE, m_aPath, FilelistCallback, this);
102 void CFileCollection::AddEntry(int64 Timestamp)
104 if(m_NumTimestamps == 0)
106 // empty list
107 m_aTimestamps[m_NumTimestamps++] = Timestamp;
109 else
111 // remove old file
112 if(m_NumTimestamps == m_MaxEntries)
114 char aBuf[512];
115 char aTimestring[TIMESTAMP_LENGTH];
116 BuildTimestring(m_aTimestamps[0], aTimestring);
117 str_format(aBuf, sizeof(aBuf), "%s/%s_%s%s", m_aPath, m_aFileDesc, aTimestring, m_aFileExt);
118 m_pStorage->RemoveFile(aBuf, IStorage::TYPE_SAVE);
121 // add entry to the sorted list
122 if(m_aTimestamps[0] > Timestamp)
124 // first entry
125 if(m_NumTimestamps < m_MaxEntries)
127 mem_move(m_aTimestamps+1, m_aTimestamps, m_NumTimestamps*sizeof(int64));
128 m_aTimestamps[0] = Timestamp;
129 ++m_NumTimestamps;
132 else if(m_aTimestamps[m_NumTimestamps-1] <= Timestamp)
134 // last entry
135 if(m_NumTimestamps == m_MaxEntries)
137 mem_move(m_aTimestamps, m_aTimestamps+1, (m_NumTimestamps-1)*sizeof(int64));
138 m_aTimestamps[m_NumTimestamps-1] = Timestamp;
140 else
141 m_aTimestamps[m_NumTimestamps++] = Timestamp;
143 else
145 // middle entry
146 int Left = 0, Right = m_NumTimestamps-1;
147 while(Right-Left > 1)
149 int Mid = (Left+Right)/2;
150 if(m_aTimestamps[Mid] > Timestamp)
151 Right = Mid;
152 else
153 Left = Mid;
156 if(m_NumTimestamps == m_MaxEntries)
158 mem_move(m_aTimestamps, m_aTimestamps+1, (Right-1)*sizeof(int64));
159 m_aTimestamps[Right-1] = Timestamp;
161 else
163 mem_move(m_aTimestamps+Right+1, m_aTimestamps+Right, (m_NumTimestamps-Right)*sizeof(int64));
164 m_aTimestamps[Right] = Timestamp;
165 ++m_NumTimestamps;
171 int CFileCollection::FilelistCallback(const char *pFilename, int IsDir, int StorageType, void *pUser)
173 CFileCollection *pThis = static_cast<CFileCollection *>(pUser);
175 // check for valid file name format
176 if(IsDir || !pThis->IsFilenameValid(pFilename))
177 return 0;
179 // extract the timestamp
180 int64 Timestamp = pThis->ExtractTimestamp(pFilename+pThis->m_FileDescLength+1);
182 // add the entry
183 pThis->AddEntry(Timestamp);
185 return 0;