mirror of https://github.com/buggins/dlangui.git
improve documentation
This commit is contained in:
parent
62a5d27aca
commit
9e69b64f1b
|
@ -1,14 +1,32 @@
|
||||||
// Written in the D programming language.
|
// Written in the D programming language.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This module contains internationalization support implementation.
|
This module contains UI internationalization support implementation.
|
||||||
|
|
||||||
Translation files contain of simple key=value pair lines.
|
UIString struct provides string container which can be either plain unicode string or id of string resource.
|
||||||
|
|
||||||
STRING_RESOURCE_ID=Translation text.
|
Translation strings are being stored in translation files, consisting of simple key=value pair lines:
|
||||||
|
---
|
||||||
|
STRING_RESOURCE_ID=Translation text 1
|
||||||
|
ANOTHER_STRING_RESOURCE_ID=Translation text 2
|
||||||
|
---
|
||||||
|
|
||||||
Supports fallback to another translation file (e.g. default language).
|
Supports fallback to another translation file (e.g. default language).
|
||||||
|
|
||||||
|
If string resource is not found neither in main nor fallback translation files, UNTRANSLATED: RESOURCE_ID will be returned.
|
||||||
|
|
||||||
|
String resources must be placed in i18n subdirectory inside one or more resource directories (set using Platform.instance.resourceDirs
|
||||||
|
property on application initialization).
|
||||||
|
|
||||||
|
File names must be language code with extension .ini (e.g. en.ini, fr.ini, es.ini)
|
||||||
|
|
||||||
|
If several files for the same language are found in (different directories) their content will be merged. It's useful to merge string resources
|
||||||
|
from DLangUI framework with resources of application.
|
||||||
|
|
||||||
|
Set interface language using Platform.instance.uiLanguage in UIAppMain during initialization of application settings:
|
||||||
|
---
|
||||||
|
Platform.instance.uiLanguage = "en";
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
Synopsis:
|
Synopsis:
|
||||||
|
@ -44,7 +62,12 @@ private import dlangui.core.linestream;
|
||||||
private import std.utf;
|
private import std.utf;
|
||||||
private import std.algorithm;
|
private import std.algorithm;
|
||||||
|
|
||||||
/** container for UI string - either raw value or string resource ID */
|
/**
|
||||||
|
Container for UI string - either raw value or string resource ID
|
||||||
|
|
||||||
|
Set resource id (string) or plain unicode text (dstring) to it, and get dstring.
|
||||||
|
|
||||||
|
*/
|
||||||
struct UIString {
|
struct UIString {
|
||||||
/** if not null, use it, otherwise lookup by id */
|
/** if not null, use it, otherwise lookup by id */
|
||||||
private dstring _value;
|
private dstring _value;
|
||||||
|
@ -61,13 +84,14 @@ struct UIString {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns string resource id
|
||||||
@property string id() const { return _id; }
|
@property string id() const { return _id; }
|
||||||
|
/// Sets string resource id
|
||||||
@property void id(string ID) {
|
@property void id(string ID) {
|
||||||
_id = ID;
|
_id = ID;
|
||||||
_value = null;
|
_value = null;
|
||||||
}
|
}
|
||||||
/** get value (either raw or translated by id) */
|
/** Get value (either raw or translated by id) */
|
||||||
@property dstring value() const {
|
@property dstring value() const {
|
||||||
if (_value !is null)
|
if (_value !is null)
|
||||||
return _value;
|
return _value;
|
||||||
|
@ -76,55 +100,59 @@ struct UIString {
|
||||||
// translate ID to dstring
|
// translate ID to dstring
|
||||||
return i18n.get(_id);
|
return i18n.get(_id);
|
||||||
}
|
}
|
||||||
/** set raw value */
|
/** Set raw value using property */
|
||||||
@property void value(dstring newValue) {
|
@property void value(dstring newValue) {
|
||||||
_value = newValue;
|
_value = newValue;
|
||||||
}
|
}
|
||||||
/** assign raw value */
|
/** Assign raw value */
|
||||||
ref UIString opAssign(dstring rawValue) {
|
ref UIString opAssign(dstring rawValue) {
|
||||||
_value = rawValue;
|
_value = rawValue;
|
||||||
_id = null;
|
_id = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/** assign ID */
|
/** Assign string resource id */
|
||||||
ref UIString opAssign(string ID) {
|
ref UIString opAssign(string ID) {
|
||||||
_id = ID;
|
_id = ID;
|
||||||
_value = null;
|
_value = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/** default conversion to dstring */
|
/** Default conversion to dstring */
|
||||||
alias value this;
|
alias value this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UIString item collection. */
|
/**
|
||||||
|
UIString item collection
|
||||||
|
|
||||||
|
Based on array.
|
||||||
|
*/
|
||||||
struct UIStringCollection {
|
struct UIStringCollection {
|
||||||
private UIString[] _items;
|
private UIString[] _items;
|
||||||
private int _length;
|
private int _length;
|
||||||
|
|
||||||
/** returns number of items */
|
/** Returns number of items */
|
||||||
@property int length() { return _length; }
|
@property int length() { return _length; }
|
||||||
/** slice */
|
/** Slice */
|
||||||
UIString[] opIndex() {
|
UIString[] opIndex() {
|
||||||
return _items[0 .. _length];
|
return _items[0 .. _length];
|
||||||
}
|
}
|
||||||
/** slice */
|
/** Slice */
|
||||||
UIString[] opSlice() {
|
UIString[] opSlice() {
|
||||||
return _items[0 .. _length];
|
return _items[0 .. _length];
|
||||||
}
|
}
|
||||||
/** slice */
|
/** Slice */
|
||||||
UIString[] opSlice(size_t start, size_t end) {
|
UIString[] opSlice(size_t start, size_t end) {
|
||||||
return _items[start .. end];
|
return _items[start .. end];
|
||||||
}
|
}
|
||||||
/** read item by index */
|
/** Read item by index */
|
||||||
UIString opIndex(size_t index) {
|
UIString opIndex(size_t index) {
|
||||||
return _items[index];
|
return _items[index];
|
||||||
}
|
}
|
||||||
/** modify item by index */
|
/** Modify item by index */
|
||||||
UIString opIndexAssign(UIString value, size_t index) {
|
UIString opIndexAssign(UIString value, size_t index) {
|
||||||
_items[index] = value;
|
_items[index] = value;
|
||||||
return _items[index];
|
return _items[index];
|
||||||
}
|
}
|
||||||
/** return unicode string for item by index */
|
/** Return unicode string for item by index */
|
||||||
dstring get(size_t index) {
|
dstring get(size_t index) {
|
||||||
return _items[index].value;
|
return _items[index].value;
|
||||||
}
|
}
|
||||||
|
@ -161,7 +189,7 @@ struct UIStringCollection {
|
||||||
add(item);
|
add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** remove all items */
|
/** Remove all items */
|
||||||
void clear() {
|
void clear() {
|
||||||
_items.length = 0;
|
_items.length = 0;
|
||||||
_length = 0;
|
_length = 0;
|
||||||
|
@ -226,14 +254,14 @@ struct UIStringCollection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UI Strings internationalization translator. */
|
/** UI Strings internationalization translator */
|
||||||
synchronized class UIStringTranslator {
|
synchronized class UIStringTranslator {
|
||||||
|
|
||||||
private UIStringList _main;
|
private UIStringList _main;
|
||||||
private UIStringList _fallback;
|
private UIStringList _fallback;
|
||||||
private string[] _resourceDirs;
|
private string[] _resourceDirs;
|
||||||
|
|
||||||
/** looks for i18n directory inside one of passed dirs, and uses first found as directory to read i18n files from */
|
/** Looks for i18n directory inside one of passed dirs, and uses first found as directory to read i18n files from */
|
||||||
void findTranslationsDir(string[] dirs ...) {
|
void findTranslationsDir(string[] dirs ...) {
|
||||||
_resourceDirs.length = 0;
|
_resourceDirs.length = 0;
|
||||||
import std.file;
|
import std.file;
|
||||||
|
@ -246,7 +274,7 @@ synchronized class UIStringTranslator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** convert resource path - append resource dir if necessary */
|
/** Convert resource path - append resource dir if necessary */
|
||||||
string[] convertResourcePaths(string filename) {
|
string[] convertResourcePaths(string filename) {
|
||||||
if (filename is null)
|
if (filename is null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -264,12 +292,13 @@ synchronized class UIStringTranslator {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// create empty translator
|
||||||
this() {
|
this() {
|
||||||
_main = new shared UIStringList();
|
_main = new shared UIStringList();
|
||||||
_fallback = new shared UIStringList();
|
_fallback = new shared UIStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** load translation file(s) */
|
/** Load translation file(s) */
|
||||||
bool load(string mainFilename, string fallbackFilename = null) {
|
bool load(string mainFilename, string fallbackFilename = null) {
|
||||||
_main.clear();
|
_main.clear();
|
||||||
_fallback.clear();
|
_fallback.clear();
|
||||||
|
@ -280,7 +309,7 @@ synchronized class UIStringTranslator {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** translate string ID to string (returns "UNTRANSLATED: id" for missing values) */
|
/** Translate string ID to string (returns "UNTRANSLATED: id" for missing values) */
|
||||||
dstring get(string id) {
|
dstring get(string id) {
|
||||||
if (id is null)
|
if (id is null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -365,7 +394,7 @@ private shared class UIStringList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Global translator object. */
|
/** Global UI translator object */
|
||||||
shared UIStringTranslator i18n;
|
shared UIStringTranslator i18n;
|
||||||
shared static this() {
|
shared static this() {
|
||||||
i18n = new shared UIStringTranslator();
|
i18n = new shared UIStringTranslator();
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
// Written in the D programming language.
|
// Written in the D programming language.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This module contains text file reader implementation.
|
|
||||||
|
This module contains text stream reader implementation
|
||||||
|
|
||||||
|
Implements class LineStream for reading of unicode text from stream and returning it by lines.
|
||||||
|
|
||||||
Support utf8, utf16, utf32 be and le encodings, and line endings - according to D language source file specification.
|
Support utf8, utf16, utf32 be and le encodings, and line endings - according to D language source file specification.
|
||||||
|
|
||||||
|
@ -51,44 +54,74 @@ import std.stream;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Support reading of file (or string in memory) by lines
|
||||||
|
|
||||||
|
Support utf8, utf16, utf32 be and le encodings, and line endings - according to D language source file specification.
|
||||||
|
|
||||||
|
Low resource consuming. Doesn't flood with GC allocations. Dup line if you want to store it somewhere.
|
||||||
|
|
||||||
|
Tracks line number.
|
||||||
|
*/
|
||||||
class LineStream {
|
class LineStream {
|
||||||
|
/// File encoding
|
||||||
public enum EncodingType {
|
public enum EncodingType {
|
||||||
|
/// plaing ASCII (character codes must be <= 127)
|
||||||
ASCII,
|
ASCII,
|
||||||
|
/// utf-8 unicode
|
||||||
UTF8,
|
UTF8,
|
||||||
|
/// utf-16 unicode big endian
|
||||||
UTF16BE,
|
UTF16BE,
|
||||||
|
/// utf-16 unicode little endian
|
||||||
UTF16LE,
|
UTF16LE,
|
||||||
|
/// utf-32 unicode big endian
|
||||||
UTF32BE,
|
UTF32BE,
|
||||||
|
/// utf-32 unicode little endian
|
||||||
UTF32LE
|
UTF32LE
|
||||||
};
|
};
|
||||||
|
|
||||||
InputStream _stream;
|
/// Error codes
|
||||||
string _filename;
|
public enum ErrorCodes {
|
||||||
ubyte[] _buf; // stream reading buffer
|
/// invalid character for current encoding
|
||||||
uint _pos; // reading position of stream buffer
|
INVALID_CHARACTER
|
||||||
uint _len; // number of bytes in stream buffer
|
};
|
||||||
bool _streamEof; // true if input stream is in EOF state
|
|
||||||
uint _line; // current line number
|
|
||||||
|
|
||||||
uint _textPos; // start of text line in text buffer
|
private InputStream _stream;
|
||||||
uint _textLen; // position of last filled char in text buffer + 1
|
private string _filename;
|
||||||
dchar[] _textBuf; // text buffer
|
private ubyte[] _buf; // stream reading buffer
|
||||||
bool _eof; // end of file, no more lines
|
private uint _pos; // reading position of stream buffer
|
||||||
|
private uint _len; // number of bytes in stream buffer
|
||||||
|
private bool _streamEof; // true if input stream is in EOF state
|
||||||
|
private uint _line; // current line number
|
||||||
|
|
||||||
|
private uint _textPos; // start of text line in text buffer
|
||||||
|
private uint _textLen; // position of last filled char in text buffer + 1
|
||||||
|
private dchar[] _textBuf; // text buffer
|
||||||
|
private bool _eof; // end of file, no more lines
|
||||||
|
|
||||||
|
/// Returns file name
|
||||||
@property string filename() { return _filename; }
|
@property string filename() { return _filename; }
|
||||||
|
/// Returns current line number
|
||||||
@property uint line() { return _line; }
|
@property uint line() { return _line; }
|
||||||
|
/// Returns file encoding EncodingType
|
||||||
@property EncodingType encoding() { return _encoding; }
|
@property EncodingType encoding() { return _encoding; }
|
||||||
|
/// Returns error code
|
||||||
@property int errorCode() { return _errorCode; }
|
@property int errorCode() { return _errorCode; }
|
||||||
|
/// Returns error message
|
||||||
@property string errorMessage() { return _errorMessage; }
|
@property string errorMessage() { return _errorMessage; }
|
||||||
|
/// Returns line where error is found
|
||||||
@property int errorLine() { return _errorLine; }
|
@property int errorLine() { return _errorLine; }
|
||||||
|
/// Returns line position (number of character in line) where error is found
|
||||||
@property int errorPos() { return _errorPos; }
|
@property int errorPos() { return _errorPos; }
|
||||||
|
|
||||||
immutable EncodingType _encoding;
|
private immutable EncodingType _encoding;
|
||||||
|
|
||||||
int _errorCode;
|
private int _errorCode;
|
||||||
string _errorMessage;
|
private string _errorMessage;
|
||||||
uint _errorLine;
|
private uint _errorLine;
|
||||||
uint _errorPos;
|
private uint _errorPos;
|
||||||
|
|
||||||
|
/// Open file with known encoding
|
||||||
protected this(InputStream stream, string filename, EncodingType encoding, ubyte[] buf, uint offset, uint len) {
|
protected this(InputStream stream, string filename, EncodingType encoding, ubyte[] buf, uint offset, uint len) {
|
||||||
_filename = filename;
|
_filename = filename;
|
||||||
_stream = stream;
|
_stream = stream;
|
||||||
|
@ -99,8 +132,8 @@ class LineStream {
|
||||||
_streamEof = _stream.eof;
|
_streamEof = _stream.eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns slice of bytes available in buffer
|
/// returns slice of bytes available in buffer
|
||||||
uint readBytes() {
|
protected uint readBytes() {
|
||||||
uint bytesLeft = _len - _pos;
|
uint bytesLeft = _len - _pos;
|
||||||
if (_streamEof || bytesLeft > QUARTER_BYTE_BUFFER_SIZE)
|
if (_streamEof || bytesLeft > QUARTER_BYTE_BUFFER_SIZE)
|
||||||
return bytesLeft;
|
return bytesLeft;
|
||||||
|
@ -117,12 +150,12 @@ class LineStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when bytes consumed from byte buffer, call this method to update position
|
// when bytes consumed from byte buffer, call this method to update position
|
||||||
void consumedBytes(uint count) {
|
protected void consumedBytes(uint count) {
|
||||||
_pos += count;
|
_pos += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reserve text buffer for specified number of characters, and return pointer to first free character in buffer
|
// reserve text buffer for specified number of characters, and return pointer to first free character in buffer
|
||||||
dchar * reserveTextBuf(uint len) {
|
protected dchar * reserveTextBuf(uint len) {
|
||||||
// create new text buffer if necessary
|
// create new text buffer if necessary
|
||||||
if (_textBuf == null) {
|
if (_textBuf == null) {
|
||||||
if (len < TEXT_BUFFER_SIZE)
|
if (len < TEXT_BUFFER_SIZE)
|
||||||
|
@ -153,12 +186,12 @@ class LineStream {
|
||||||
return _textBuf.ptr + _textLen;
|
return _textBuf.ptr + _textLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendedText(uint len) {
|
protected void appendedText(uint len) {
|
||||||
//writeln("appended ", len, " chars of text"); //:", _textBuf[_textLen .. _textLen + len]);
|
//writeln("appended ", len, " chars of text"); //:", _textBuf[_textLen .. _textLen + len]);
|
||||||
_textLen += len;
|
_textLen += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setError(int code, string message, uint errorLine, uint errorPos) {
|
protected void setError(int code, string message, uint errorLine, uint errorPos) {
|
||||||
_errorCode = code;
|
_errorCode = code;
|
||||||
_errorMessage = message;
|
_errorMessage = message;
|
||||||
_errorLine = errorLine;
|
_errorLine = errorLine;
|
||||||
|
@ -166,9 +199,12 @@ class LineStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
// override to decode text
|
// override to decode text
|
||||||
abstract uint decodeText();
|
protected abstract uint decodeText();
|
||||||
|
|
||||||
|
/// Unknown line position
|
||||||
immutable static uint LINE_POSITION_UNDEFINED = uint.max;
|
immutable static uint LINE_POSITION_UNDEFINED = uint.max;
|
||||||
|
|
||||||
|
/// Read line from stream
|
||||||
public dchar[] readLine() {
|
public dchar[] readLine() {
|
||||||
if (_errorCode != 0) {
|
if (_errorCode != 0) {
|
||||||
//writeln("error ", _errorCode, ": ", _errorMessage, " in line ", _errorLine);
|
//writeln("error ", _errorCode, ": ", _errorMessage, " in line ", _errorLine);
|
||||||
|
@ -250,11 +286,11 @@ class LineStream {
|
||||||
return _textBuf[lineStart .. lineEnd];
|
return _textBuf[lineStart .. lineEnd];
|
||||||
}
|
}
|
||||||
|
|
||||||
immutable static int TEXT_BUFFER_SIZE = 1024;
|
protected immutable static int TEXT_BUFFER_SIZE = 1024;
|
||||||
immutable static int BYTE_BUFFER_SIZE = 512;
|
protected immutable static int BYTE_BUFFER_SIZE = 512;
|
||||||
immutable static int QUARTER_BYTE_BUFFER_SIZE = BYTE_BUFFER_SIZE / 4;
|
protected immutable static int QUARTER_BYTE_BUFFER_SIZE = BYTE_BUFFER_SIZE / 4;
|
||||||
|
|
||||||
// factory for string parser
|
/// Factory method for string parser
|
||||||
public static LineStream create(string code, string filename = "") {
|
public static LineStream create(string code, string filename = "") {
|
||||||
uint len = cast(uint)code.length;
|
uint len = cast(uint)code.length;
|
||||||
ubyte[] data = new ubyte[len + 3];
|
ubyte[] data = new ubyte[len + 3];
|
||||||
|
@ -268,7 +304,7 @@ class LineStream {
|
||||||
return create(stream, filename);
|
return create(stream, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// factory
|
/// Factory for InputStream parser
|
||||||
public static LineStream create(InputStream stream, string filename) {
|
public static LineStream create(InputStream stream, string filename) {
|
||||||
ubyte[] buf = new ubyte[BYTE_BUFFER_SIZE];
|
ubyte[] buf = new ubyte[BYTE_BUFFER_SIZE];
|
||||||
buf[0] = buf[1] = buf[2] = buf[3] = 0;
|
buf[0] = buf[1] = buf[2] = buf[3] = 0;
|
||||||
|
@ -293,13 +329,12 @@ class LineStream {
|
||||||
protected bool invalidCharFlag;
|
protected bool invalidCharFlag;
|
||||||
protected void invalidCharError() {
|
protected void invalidCharError() {
|
||||||
uint pos = _textLen - _textPos + 1;
|
uint pos = _textLen - _textPos + 1;
|
||||||
setError(1, "Invalid character in line " ~ to!string(_line) ~ ":" ~ to!string(pos), _line, pos);
|
setError(ErrorCodes.INVALID_CHARACTER, "Invalid character in line " ~ to!string(_line) ~ ":" ~ to!string(pos), _line, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class AsciiLineStream : LineStream {
|
||||||
class AsciiLineStream : LineStream {
|
|
||||||
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
||||||
super(stream, filename, EncodingType.ASCII, buf, 0, len);
|
super(stream, filename, EncodingType.ASCII, buf, 0, len);
|
||||||
}
|
}
|
||||||
|
@ -332,7 +367,7 @@ class AsciiLineStream : LineStream {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Utf8LineStream : LineStream {
|
private class Utf8LineStream : LineStream {
|
||||||
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
||||||
super(stream, filename, EncodingType.UTF8, buf, 3, len);
|
super(stream, filename, EncodingType.UTF8, buf, 3, len);
|
||||||
}
|
}
|
||||||
|
@ -448,7 +483,7 @@ class Utf8LineStream : LineStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Utf16beLineStream : LineStream {
|
private class Utf16beLineStream : LineStream {
|
||||||
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
||||||
super(stream, filename, EncodingType.UTF16BE, buf, 2, len);
|
super(stream, filename, EncodingType.UTF16BE, buf, 2, len);
|
||||||
}
|
}
|
||||||
|
@ -482,7 +517,7 @@ class Utf16beLineStream : LineStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Utf16leLineStream : LineStream {
|
private class Utf16leLineStream : LineStream {
|
||||||
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
||||||
super(stream, filename, EncodingType.UTF16LE, buf, 2, len);
|
super(stream, filename, EncodingType.UTF16LE, buf, 2, len);
|
||||||
}
|
}
|
||||||
|
@ -516,7 +551,7 @@ class Utf16leLineStream : LineStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Utf32beLineStream : LineStream {
|
private class Utf32beLineStream : LineStream {
|
||||||
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
||||||
super(stream, filename, EncodingType.UTF32BE, buf, 4, len);
|
super(stream, filename, EncodingType.UTF32BE, buf, 4, len);
|
||||||
}
|
}
|
||||||
|
@ -555,7 +590,7 @@ class Utf32beLineStream : LineStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Utf32leLineStream : LineStream {
|
private class Utf32leLineStream : LineStream {
|
||||||
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
this(InputStream stream, string filename, ubyte[] buf, uint len) {
|
||||||
super(stream, filename, EncodingType.UTF32LE, buf, 4, len);
|
super(stream, filename, EncodingType.UTF32LE, buf, 4, len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
// Written in the D programming language.
|
// Written in the D programming language.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This module contains logger implementation.
|
This module provides logging utilities.
|
||||||
|
|
||||||
|
|
||||||
|
Use Log class static methods.
|
||||||
|
|
||||||
Synopsis:
|
Synopsis:
|
||||||
|
|
||||||
----
|
----
|
||||||
import dlangui.core.logger;
|
import dlangui.core.logger;
|
||||||
|
|
||||||
|
// setup:
|
||||||
|
|
||||||
// use stderror for logging
|
// use stderror for logging
|
||||||
setStderrLogger();
|
setStderrLogger();
|
||||||
// set log level
|
// set log level
|
||||||
setLogLevel(LogLeve.Debug);
|
setLogLevel(LogLeve.Debug);
|
||||||
|
|
||||||
|
// usage:
|
||||||
|
|
||||||
// log debug message
|
// log debug message
|
||||||
Log.d("mouse clicked at ", x, ",", y);
|
Log.d("mouse clicked at ", x, ",", y);
|
||||||
// log error message
|
// log error message
|
||||||
Log.d("exception while reading file", e);
|
Log.e("exception while reading file", e);
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Copyright: Vadim Lopatin, 2014
|
Copyright: Vadim Lopatin, 2014
|
||||||
|
@ -30,40 +34,75 @@ module dlangui.core.logger;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import std.datetime;
|
import std.datetime;
|
||||||
|
|
||||||
|
/// Log levels
|
||||||
enum LogLevel : int {
|
enum LogLevel : int {
|
||||||
|
/// Fatal error, cannot resume
|
||||||
Fatal,
|
Fatal,
|
||||||
|
/// Error
|
||||||
Error,
|
Error,
|
||||||
|
/// Warning
|
||||||
Warn,
|
Warn,
|
||||||
|
/// Informational message
|
||||||
Info,
|
Info,
|
||||||
|
/// Debug message
|
||||||
Debug,
|
Debug,
|
||||||
|
/// Tracing message
|
||||||
Trace
|
Trace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns timestamp in milliseconds since 1970 UTC similar to Java System.currentTimeMillis()
|
||||||
long currentTimeMillis() {
|
long currentTimeMillis() {
|
||||||
return std.datetime.Clock.currStdTime / 10000;
|
return std.datetime.Clock.currStdTime / 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
Logging utilities
|
||||||
|
|
||||||
|
Setup example:
|
||||||
|
----
|
||||||
|
// setup:
|
||||||
|
// use stderror for logging
|
||||||
|
setStderrLogger();
|
||||||
|
// set log level
|
||||||
|
setLogLevel(LogLeve.Debug);
|
||||||
|
----
|
||||||
|
|
||||||
|
Logging example:
|
||||||
|
----
|
||||||
|
// log debug message
|
||||||
|
Log.d("mouse clicked at ", x, ",", y);
|
||||||
|
// log error message
|
||||||
|
Log.e("exception while reading file", e);
|
||||||
|
----
|
||||||
|
|
||||||
|
*/
|
||||||
synchronized class Log {
|
synchronized class Log {
|
||||||
static {
|
static:
|
||||||
private LogLevel logLevel = LogLevel.Info;
|
private LogLevel logLevel = LogLevel.Info;
|
||||||
private std.stdio.File logFile;
|
private std.stdio.File logFile;
|
||||||
|
|
||||||
|
/// Redirects output to stdout
|
||||||
void setStdoutLogger() {
|
void setStdoutLogger() {
|
||||||
logFile = stdout;
|
logFile = stdout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Redirects output to stderr
|
||||||
void setStderrLogger() {
|
void setStderrLogger() {
|
||||||
logFile = stderr;
|
logFile = stderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Redirects output to file
|
||||||
void setFileLogger(File file) {
|
void setFileLogger(File file) {
|
||||||
logFile = file;
|
logFile = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets log level (one of LogLevel)
|
||||||
void setLogLevel(LogLevel level) {
|
void setLogLevel(LogLevel level) {
|
||||||
logLevel = level;
|
logLevel = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Log level to name helper function
|
||||||
string logLevelName(LogLevel level) {
|
string logLevelName(LogLevel level) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case LogLevel.Fatal: return "F";
|
case LogLevel.Fatal: return "F";
|
||||||
|
@ -75,6 +114,7 @@ synchronized class Log {
|
||||||
default: return "?";
|
default: return "?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Log message with arbitrary log level
|
||||||
void log(S...)(LogLevel level, S args) {
|
void log(S...)(LogLevel level, S args) {
|
||||||
if (logLevel >= level && logFile.isOpen) {
|
if (logLevel >= level && logFile.isOpen) {
|
||||||
SysTime ts = Clock.currTime();
|
SysTime ts = Clock.currTime();
|
||||||
|
@ -83,29 +123,34 @@ synchronized class Log {
|
||||||
logFile.flush();
|
logFile.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Log verbose / trace message
|
||||||
void v(S...)(S args) {
|
void v(S...)(S args) {
|
||||||
if (logLevel >= LogLevel.Trace && logFile.isOpen)
|
if (logLevel >= LogLevel.Trace && logFile.isOpen)
|
||||||
log(LogLevel.Trace, args);
|
log(LogLevel.Trace, args);
|
||||||
}
|
}
|
||||||
|
/// Log debug message
|
||||||
void d(S...)(S args) {
|
void d(S...)(S args) {
|
||||||
if (logLevel >= LogLevel.Debug && logFile.isOpen)
|
if (logLevel >= LogLevel.Debug && logFile.isOpen)
|
||||||
log(LogLevel.Debug, args);
|
log(LogLevel.Debug, args);
|
||||||
}
|
}
|
||||||
|
/// Log info message
|
||||||
void i(S...)(S args) {
|
void i(S...)(S args) {
|
||||||
if (logLevel >= LogLevel.Info && logFile.isOpen)
|
if (logLevel >= LogLevel.Info && logFile.isOpen)
|
||||||
log(LogLevel.Info, args);
|
log(LogLevel.Info, args);
|
||||||
}
|
}
|
||||||
|
/// Log warn message
|
||||||
void w(S...)(S args) {
|
void w(S...)(S args) {
|
||||||
if (logLevel >= LogLevel.Warn && logFile.isOpen)
|
if (logLevel >= LogLevel.Warn && logFile.isOpen)
|
||||||
log(LogLevel.Warn, args);
|
log(LogLevel.Warn, args);
|
||||||
}
|
}
|
||||||
|
/// Log error message
|
||||||
void e(S...)(S args) {
|
void e(S...)(S args) {
|
||||||
if (logLevel >= LogLevel.Error && logFile.isOpen)
|
if (logLevel >= LogLevel.Error && logFile.isOpen)
|
||||||
log(LogLevel.Error, args);
|
log(LogLevel.Error, args);
|
||||||
}
|
}
|
||||||
|
/// Log fatal error message
|
||||||
void f(S...)(S args) {
|
void f(S...)(S args) {
|
||||||
if (logLevel >= LogLevel.Fatal && logFile.isOpen)
|
if (logLevel >= LogLevel.Fatal && logFile.isOpen)
|
||||||
log(LogLevel.Fatal, args);
|
log(LogLevel.Fatal, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue