int Luhn::Mod10(const AnyString& s)
	{
		// The string must have at least one char
		if (s.size() > 1)
		{
			// The algorithm :
			// 1 - Counting from the check digit, which is the rightmost, and moving
			//     left, double the value of every second digit.
			// 2 - Sum the digits of the products together with the undoubled digits
			//     from the original number.
			// 3 - If the total ends in 0 (put another way, if the total modulo 10 is
			//     congruent to 0), then the number is valid according to the Luhn formula
			//
			static const int prefetch[] = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};

			int sum = 0;
			bool alternate = true;

			const AnyString::iterator end = s.end();
			// For each char
			for (AnyString::iterator i = s.begin(); end != i; ++i)
			{
				// Each char in the string must be a digit
				if (!String::IsDigit(i.value()))
					return false;
				// The `real` digit
				int n = i.value() - '0';
				// Computing the sum
				sum += (alternate = !alternate) ? prefetch[n] : n;
			}
			return sum % 10;
		}
		return -1;
	}
Exemple #2
0
DBI::Error Transaction::truncate(const AnyString& tablename)
{
    if (YUNI_UNLIKELY(not IsValidIdentifier(tablename)))
        return errInvalidIdentifier;

    assert(!(!pChannel));

    // the adapter
    ::yn_dbi_adapter& adapter = pChannel->adapter;

    // The DBI interface should provide the most appropriate way for
    // truncating a table (autoincrement / cascade...)
    if (YUNI_LIKELY(adapter.truncate))
    {
        return (DBI::Error) adapter.truncate(adapter.dbh, tablename.c_str(), tablename.size());
    }
    else
    {
        // Fallback to a failsafe method
        // -- stmt << "TRUNCATE " << tablename << ';';
        // The SQL command Truncate is not supported by all databases. `DELETE FROM`
        // is not  the most efficient way for truncating a table
        // but it should work almost everywhere
        String stmt;
        stmt << "DELETE FROM " << tablename << ';';
        return perform(stmt);
    }
}
Exemple #3
0
Cursor Transaction::prepare(const AnyString& stmt)
{
    assert(!(!pChannel));

    // the adapter
    ::yn_dbi_adapter& adapter = pChannel->adapter;

    if (YUNI_UNLIKELY(nullHandle == pTxHandle))
    {
        if (errNone != pChannel->begin(pTxHandle))
            return Cursor(adapter, nullptr);
    }

    // query handle
    void* handle = nullptr;

    if (YUNI_LIKELY(not stmt.empty() and adapter.dbh))
    {
        assert(adapter.query_new != NULL  and "invalid adapter query_new");
        assert(adapter.query_ref_acquire != NULL and "invalid adapter query_ref_acquire");
        assert(adapter.query_ref_release != NULL and "invalid adapter query_ref_release");

        adapter.query_new(&handle, adapter.dbh, stmt.c_str(), stmt.size());
    }

    return Cursor(adapter, handle);
}
Exemple #4
0
	Yuni::IO::NodeType TypeOf(const AnyString& filename)
	{
		if (filename.empty())
			return Yuni::IO::typeUnknown;

		# ifdef YUNI_OS_WINDOWS
		const char* p = filename.c_str();
		unsigned int len = filename.size();
		if (p[len - 1] == '\\' or p[len - 1] == '/')
		{
			if (!--len)
			{
				# ifdef YUNI_OS_WINDOWS
				return Yuni::IO::typeUnknown;
				# else
				// On Unixes, `/` is a valid folder
				return Yuni::IO::typeFolder;
				# endif
			}
		}

		// Driver letters
		if (len == 2 and p[1] == ':')
			return Yuni::IO::typeFolder;

		String  norm;
		Yuni::IO::Normalize(norm, AnyString(p, len));
		// Conversion into wchar_t
		Private::WString<true> wstr(norm);
		if (wstr.empty())
			return Yuni::IO::typeUnknown;

		WIN32_FILE_ATTRIBUTE_DATA infoFile;
		if (!GetFileAttributesExW(wstr.c_str(), GetFileExInfoStandard, &infoFile))
			return Yuni::IO::typeUnknown;

		return ((infoFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
			? Yuni::IO::typeFolder
			: Yuni::IO::typeFile;

		# else // WINDOWS

		struct stat s;
		if (stat(filename.c_str(), &s) != 0)
			return Yuni::IO::typeUnknown;

		return (S_ISDIR(s.st_mode))
			? Yuni::IO::typeFolder
			: Yuni::IO::typeFile;
		# endif
	}
Exemple #5
0
DBI::Error Transaction::perform(const AnyString& script)
{
    assert(!(!pChannel));

    // the adapter
    ::yn_dbi_adapter& adapter = pChannel->adapter;
    assert(adapter.query_exec != NULL);

    if (YUNI_LIKELY(nullHandle != pTxHandle))
    {
        return (DBI::Error) adapter.query_exec(adapter.dbh, script.c_str(), script.size());
    }
    else
    {
        // start a new transaction
        DBI::Error error = pChannel->begin(pTxHandle);

        if (YUNI_LIKELY(error == errNone))
            error = (DBI::Error) adapter.query_exec(adapter.dbh, script.c_str(), script.size());

        return error;
    }
}
Exemple #6
0
	bool Size(const AnyString& filename, uint64& value)
	{
		unsigned int len = filename.size();
		if (!len)
		{
			value = 0u;
			return false;
		}

		const char* const p = filename.c_str();

		if (p[len - 1] == '\\' || p[len - 1] == '/')
			--len;

		// Driver letters
		if (len == 2 && p[1] == ':')
		{
			value = 0u;
			return true;
		}

		String  norm;
		Yuni::IO::Normalize(norm, p, len);
		// Conversion into wchar_t
		Private::WString<true> wstr(norm);
		if (wstr.empty())
		{
			value = 0u;
			return false;
		}

		HANDLE hndl = CreateFileW(wstr.c_str(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		if (hndl == INVALID_HANDLE_VALUE)
		{
			value = 0u;
			return false;
		}
		LARGE_INTEGER v;
		if (!GetFileSizeEx(hndl, &v))
		{
			CloseHandle(hndl);
			value = 0u;
			return false;
		}
		value = (uint64) v.QuadPart;

		CloseHandle(hndl);
		return true;
	}
Exemple #7
0
	Yuni::IO::Error Delete(const AnyString& filename)
	{
		// DeleteFile is actually a macro and will be replaced by DeleteFileW
		// with Visual Studio. Consequently we can not use the word DeleteFile.....

		if (filename.empty())
			return Yuni::IO::errUnknown;

		# ifndef YUNI_OS_WINDOWS

		return (unlink(filename.c_str()))
			? Yuni::IO::errUnknown
			: Yuni::IO::errNone;

		# else

		const char* const p = filename.c_str();
		uint len = filename.size();

		if (p[len - 1] == '\\' or p[len - 1] == '/')
			--len;

		// Driver letters
		if (len == 2 and p[1] == ':')
			return Yuni::IO::errBadFilename;

		String norm;
		Yuni::IO::Normalize(norm, AnyString(p, len));

		// Conversion into wchar_t
		WString wstr(norm, true);
		if (wstr.empty())
			return Yuni::IO::errUnknown;
		wstr.replace('/', '\\');

		return (DeleteFileW(wstr.c_str()))
			? Yuni::IO::errNone
			: Yuni::IO::errUnknown;
		# endif
	}
Exemple #8
0
	static bool UnixMake(const AnyString& path, uint mode)
	{
		const uint len = path.size();
		char* buffer = new char[len + 1];
		YUNI_MEMCPY(buffer, len, path.c_str(), len);
		buffer[len] = '\0';
		char* pt = buffer;
		char tmp;

		do
		{
			if ('\\' == *pt or '/' == *pt or '\0' == *pt)
			{
				tmp = *pt;
				*pt = '\0';
				if ('\0' != buffer[0] and '\0' != buffer[1] and '\0' != buffer[2])
				{
					if (mkdir(buffer, static_cast<mode_t>(mode)) < 0)
					{
						if (errno != EEXIST and errno != EISDIR and errno != ENOSYS)
						{
							delete[] buffer;
							return false;
						}
					}
				}
				if ('\0' == tmp)
					break;
				*pt = tmp;
			}
			++pt;
		}
		while (true);

		delete[] buffer;
		return true;
	}
Exemple #9
0
	EventPropagation TextEditor::charInput(const AnyString& str)
	{
		switch (str[0])
		{
			// Backspace
			case 0x08:
				for (uint i = 0; i < str.size(); ++i)
				{
					// Cannot use backspace when at beginning of file
					if (0 == pCursorPos.y && 1 == pCursorPos.x)
						return epStop;
					// When at beginning of line but not on first line, move up
					if (0 == pCursorPos.y && pCursorPos.x > 1)
						cursorPos(pCursorPos.x - 1, columnCount(pCursorPos.x - 1));
					else
						cursorPos(pCursorPos.x, pCursorPos.y - 1);
					// Erase
					pText.erase(cursorToByte(pCursorPos), 1);
				}
				invalidate();
				break;
			// Space
			case ' ':
				pText.insert(cursorToByte(pCursorPos), str);
				pCursorPos.x += str.size();
				invalidate();
				break;
			// Tab
			case '\t':
				pText.insert(cursorToByte(pCursorPos), str);
				cursorPos(pCursorPos.x, pCursorPos.y + str.size() * pTabWidth);
				invalidate();
				break;
			// Carriage Return
			case '\r':
			// New Line / Line Feed
			case '\n':
				for (uint i = 0; i < str.size(); ++i)
					pText.insert(cursorToByte(pCursorPos), '\n');
				pCursorPos.y += str.size();
				invalidate();
				break;
			// Normal displayable characters
			default:
				// Normal ASCII
				if ((uint8)str[0] < 0x80)
				{
					// Non-displayable characters are ignored
					std::locale loc;
					if (!std::isgraph(str[0], loc))
						break;
				}
				pText.insert(cursorToByte(pCursorPos), str);

				// Advance the cursor
				pCursorPos.x += str.utf8size();
				invalidate();
				break;
		}
		return epStop;
	}
	static bool DecodeURLQuery(KeyValueStore& params, const AnyString& query)
	{
		// note: mongoose does not provide the fragment here, so we don't have
		// to check it

		// Some tests are already done before calling this method
		assert(not query.empty());

		String key; // temporary string for parameters handling
		uint offset = 0;
		uint start = 0;
		AnyString value;
		do
		{
			offset = query.find_first_of("=&", offset);
			if (offset >= query.size())
			{
				// ignoring fields with empty value (using default)
				break;
			}
			if (query[offset] == '=')
			{
				key.assign(query, offset - start, start);
				if (key.empty()) // malformed url. aborting
					return false;

				++offset;

				// FIXME !!!! &amp; are not properly handled !!!!!!!!!!!!
				uint ampersand = offset;
				ampersand = query.find('&', ampersand);
				if (ampersand >= query.size())
				{
					value.adapt(query, query.size() - offset, offset);
					ampersand = query.size();
				}
				else
					value.adapt(query, ampersand - offset, offset);

				if (not value.empty())
				{
					KeyValueStore::iterator i = params.find(key);
					if (i != params.end())
					{
						// the item has been found !
						params[key] = value;
					}
				}

				offset = ampersand;
			}
			else
			{
				// ignoring fields with empty value (using default)
			}

			// updating offsets
			start = ++offset;
		}
		while (true);
		return true;
	}
	void WString::prepareWString(const AnyString& string, bool uncprefix)
	{
		if (string.empty())
		{
			if (uncprefix)
			{
				pSize = 4;
				pWString = (wchar_t*)::realloc(pWString, sizeof(wchar_t) * 5);
				pWString[0] = L'\\';
				pWString[1] = L'\\';
				pWString[2] = L'?';
				pWString[3] = L'\\';
				pWString[4] = L'\0';
			}
			else
				clear();
			return;
		}

		if (string.size() > INT_MAX)
		{
			clear();
			return;
		}

		// Offset according to the presence of the UNC prefix
		const uint offset = (not uncprefix) ? 0 : 4;

		#ifdef YUNI_OS_WINDOWS
		{
			// Allocate and convert the C-String. Several iterations may be required
			// for allocating enough room for the conversion.
			const int sizeRequired = MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.size(), nullptr, 0);
			if (sizeRequired <= 0)
			{
				clear();
				return;
			}

			pSize = sizeRequired + offset;

			pWString = (wchar_t*) realloc(pWString, sizeof(wchar_t) * (pSize + 1));
			if (nullptr == pWString) // Impossible to allocate the buffer. Aborting.
			{
				clear();
				return;
			}

			// Converting into Wide String
			const int n = MultiByteToWideChar(CP_UTF8, 0, string.c_str(), static_cast<int>(string.size()), pWString + offset, static_cast<int>(pSize - offset));
			if (n != sizeRequired)
			{
				assert(false and "most likely an error");
				clear();
				return;
			}
		}
		#else
		{
			const char* wcstr = string.c_str();

			mbstate_t state;
			memset (&state, '\0', sizeof (state));

			size_t sizeRequired = mbsnrtowcs(nullptr, &wcstr, string.size(), 0, &state);
			if (0 == sizeRequired or (size_t) -1 == sizeRequired)
			{
				clear();
				return;
			}

			pSize = sizeRequired + offset;

			pWString = (wchar_t*) realloc(pWString, sizeof(wchar_t) * (pSize + 1));
			if (nullptr == pWString) // Impossible to allocate the buffer. Aborting.
			{
				clear();
				return;
			}

			memset (&state, '\0', sizeof (state));
			size_t written = mbsnrtowcs(pWString + offset, &wcstr, string.size(), pSize - offset, &state);
			if (0 == written or (size_t) -1 == written)
			{
				clear();
				return;
			}
		}
		#endif


		// prepend the Windows UNC prefix
		if (uncprefix)
		{
			pWString[0] = L'\\';
			pWString[1] = L'\\';
			pWString[2] = L'?';
			pWString[3] = L'\\';
		}

		// always ensure that the string is zero terminated
		pWString[pSize] = L'\0';
	}
Exemple #12
-1
	bool Resize(const AnyString& filename, uint64_t size)
	{
		if (not filename.empty())
		{
			if (size < std::numeric_limits<off_t>::max())
			{
				#ifndef YUNI_OS_WINDOWS
				{
					assert((filename.c_str())[filename.size()] == '\0');
					#ifdef YUNI_OS_MAC
					int fd = open(filename.c_str(), O_WRONLY|O_CREAT, 0644);
					#else
					int fd = open(filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644);
					#endif
					if (fd != -1)
					{
						bool success = (0 == ftruncate(fd, static_cast<off_t>(size)));
						close(fd);
						return success;
					}
				}
				#else
				{
					WString wstr(filename, true);
					if (not wstr.empty())
					{
						HANDLE hndl = CreateFileW(wstr.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
						if (hndl)
						{
							LARGE_INTEGER li;
							li.QuadPart = size;
							DWORD dwPtr = SetFilePointer(hndl, li.LowPart, &li.HighPart, FILE_BEGIN);
							if (dwPtr != INVALID_SET_FILE_POINTER)
								SetEndOfFile(hndl);
							CloseHandle(hndl);
							return true;
						}
					}
				}
				#endif
			}
		}
		return false;
	}