Subversion Repositories svn.mios32

Rev

Rev 1556 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
928 tk 1
/* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
2
// $Id: HexTextEditor.cpp 1724 2013-03-28 20:23:40Z tk $
3
/*
4
 * Text Editor variant which allows to edit hex bytes
5
 *
6
 * ==========================================================================
7
 *
8
 *  Copyright (C) 2010 Thorsten Klose (tk@midibox.org)
9
 *  Licensed for personal non-commercial use only.
10
 *  All other rights reserved.
11
 *
12
 * ==========================================================================
13
 */
14
 
15
#include "HexTextEditor.h"
16
 
17
 
18
//==============================================================================
19
HexTextEditor::HexTextEditor(Label *_statusLabel)
20
    : TextEditor(String::empty)
21
    , statusLabel(_statusLabel)
22
    , bufferedText(String::empty)
23
{
24
    setMultiLine(true);
25
    setReturnKeyStartsNewLine(true);
26
    setReadOnly(false);
27
    setScrollbarsShown(true);
28
    setCaretVisible(true);
29
    setPopupMenuEnabled(true);
30
    setInputRestrictions(1000000, T("0123456789ABCDEFabcdef \n"));
949 philetaylo 31
#if JUCE_MAJOR_VERSION==1 && JUCE_MINOR_VERSION<51
1189 tk 32
#if defined(JUCE_WIN32)
928 tk 33
    setFont(Font(Typeface::defaultTypefaceNameMono, 10.0, 0));
34
#else
35
    setFont(Font(Typeface::defaultTypefaceNameMono, 13.0, 0));
36
#endif
949 philetaylo 37
#else
1189 tk 38
#if defined(JUCE_WIN32)
949 philetaylo 39
    setFont(Font(Font::getDefaultMonospacedFontName(), 10.0, 0));
40
#else
41
    setFont(Font(Font::getDefaultMonospacedFontName(), 13.0, 0));
42
#endif
43
#endif
44
    addListener(this);
928 tk 45
 
46
    setSize(600, 200);
47
}
48
 
49
HexTextEditor::~HexTextEditor()
50
{
51
}
52
 
53
//==============================================================================
54
void HexTextEditor::clear()
55
{
56
    bufferedText = String::empty;
57
    TextEditor::clear();
58
}
59
 
60
//==============================================================================
61
void HexTextEditor::textEditorTextChanged(TextEditor &editor)
62
{
63
    String hexStr = getText();
64
    int size = hexStr.length();
949 philetaylo 65
#if JUCE_MAJOR_VERSION==1 && JUCE_MINOR_VERSION<51
66
    const char *strBuffer = (const char *)hexStr; // for *much* faster access! The String[pos] handling of Juce should be optimized!
67
#else
1724 tk 68
    const char *strBuffer = hexStr.toUTF8().getAddress(); // for *much* faster access! The String[pos] handling of Juce should be optimized!
949 philetaylo 69
#endif
928 tk 70
 
71
    int numBytes = 0;
72
    int charCounter = 0;
73
    bool invalidBytesFound = false;
74
 
75
    // we assume that only hex digits are entered (ensured via setInputRestrictions())
76
    for(int pos=0; pos<size; ++pos) {
77
        if( strBuffer[pos] == ' ' || strBuffer[pos] == '\n' ) {
78
            if( charCounter > 0 )
79
                ++numBytes;
80
            charCounter = 0;
81
        } else {
82
            if( ++charCounter > 2 )
83
                invalidBytesFound = true;
84
        }
85
    }
86
    if( charCounter > 0 )
87
        ++numBytes;
88
 
1556 tk 89
    if( isEnabled() && isVisible() ) {
90
        if( invalidBytesFound )
91
            statusLabel->setText(T("Invalid Syntax!"), true);
92
        else if( numBytes == 0 )
93
            statusLabel->setText(String::empty, true);
94
        else if( numBytes == 1 )
95
            statusLabel->setText(T("1 byte"), true);
96
        else
97
            statusLabel->setText(String(numBytes) + T(" bytes"), true);
98
    }
928 tk 99
}
100
 
101
void HexTextEditor::textEditorReturnKeyPressed(TextEditor &editor)
102
{
103
}
104
 
105
void HexTextEditor::textEditorEscapeKeyPressed(TextEditor &editor)
106
{
107
}
108
 
109
void HexTextEditor::textEditorFocusLost(TextEditor &editor)
110
{
111
}
112
 
113
//==============================================================================
114
void HexTextEditor::setBinary(uint8 *buffer, const int &size)
115
{
116
    bufferedText = String::empty;
117
 
118
    clear();
119
    int64 lineBegin = 0;
120
    for(int64 pos=0; pos<size; ++pos) {
121
        if( buffer[pos] == 0xf7 || pos == (size-1) ) {
122
            if( bufferedText.length() > 0 )
123
                bufferedText += T("\n");
124
            bufferedText += String::toHexString(&buffer[lineBegin], pos-lineBegin+1);
125
            lineBegin = pos+1;
126
        }
127
    }
128
 
129
    setText(bufferedText, true);
130
}
131
 
132
 
133
//==============================================================================
134
void HexTextEditor::addBinary(uint8 *buffer, const int &size)
135
{
936 tk 136
    if( size > 0 ) {
928 tk 137
#if 0
936 tk 138
        String hexStr = String::toHexString(buffer, size);
139
        if( !isEmpty() )
140
            insertTextAtCursor(T("\n"));
141
        insertTextAtCursor(hexStr);
928 tk 142
#else
936 tk 143
        // works faster! Will be removed once the Juce TextEditor has been optimized
144
        if( bufferedText != String::empty )
145
            bufferedText += T("\n");
146
        bufferedText += String::toHexString(buffer, size);
147
        setText(bufferedText);
928 tk 148
#endif
936 tk 149
    }
928 tk 150
}
151
 
152
//==============================================================================
153
Array<uint8> HexTextEditor::getBinary(void)
154
{
155
    String hexStr = getText();
156
    int size = hexStr.length();
157
 
949 philetaylo 158
#if JUCE_MAJOR_VERSION==1 && JUCE_MINOR_VERSION<51
159
    const char *strBuffer = (const char *)hexStr; // for *much* faster access! The String[pos] handling of Juce should be optimized!
160
#else
1724 tk 161
    const char *strBuffer = hexStr.toUTF8().getAddress(); // for *much* faster access! The String[pos] handling of Juce should be optimized!
949 philetaylo 162
#endif
163
 
928 tk 164
    Array<uint8> retArray;
165
    int charCounter = 0;
166
    uint8 b = 0;
167
 
168
    // we assume that only hex digits are entered (ensured via setInputRestrictions())
169
    for(int pos=0; pos<size; ++pos) {
170
        char c = strBuffer[pos];
171
        if( c == ' ' || c == '\n' ) {
172
            if( charCounter > 0 )
173
                retArray.add(b);
174
            charCounter = 0;
175
        } else {
176
            uint8 nibble = 0;
177
            if( c >= '0' && c <= '9' )
178
                nibble = c - '0';
179
            else if( c >= 'A' && c <= 'F' )
180
                nibble = c - 'A' + 10;
181
            else if( c >= 'a' && c <= 'f' )
182
                nibble = c - 'a' + 10;
183
 
184
            if( charCounter == 0 )
185
                b = nibble << 4;
186
            else if( charCounter == 1 )
187
                b |= nibble;
188
            else {
189
                retArray.clear();
190
                return retArray;
191
            }
192
            ++charCounter;
193
        }
194
    }
195
 
196
    if( charCounter > 0 )
197
        retArray.add(b);
198
 
199
    return retArray;
200
}