* Resolved a TODO and implemented an is_valid_utf8() function that replaces the

former is_valid_ascii(). This function is now also exported in the header.
* Some cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28975 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-01-21 08:30:24 +00:00
parent 2409f4caa6
commit 8bc239bc55
2 changed files with 146 additions and 103 deletions
+46 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2006, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2004-2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
@@ -28,24 +28,58 @@ static const uint32 kHexByteWidth = 3;
// these are determined by the implementation of DataView::ConvertLine()
/** This function checks if the buffer contains a valid ASCII
* string, following the convention from the DataView::ConvertLine()
* method: everything that's not replaced by a '.' there will be
* accepted.
/*! This function checks if the buffer contains a valid UTF-8
string, following the convention from the DataView::ConvertLine()
method: everything that's not replaced by a '.' will be accepted.
*/
// ToDo: a valid UTF-8 string would be nicer...
bool
is_valid_ascii(uint8 *data, size_t size)
is_valid_utf8(uint8 *data, size_t size)
{
for (size_t i = 0; i < size; i++) {
// accept a terminating null byte
if (i == size - 1 && data[0] == '\0')
return true;
if (data[i] < ' ' || data[i] == 0x7f || data[i] & 0x80)
if ((data[i] & 0x80) == 0) {
// a single byte character
if (data[i] < ' ' || data[i] == 0x7f)
return false;
continue;
}
if ((data[i] & 0xc0) == 0x80) {
// not a proper multibyte start
return false;
}
// start of a multibyte character
uint8 mask = 0x80;
uint32 result = (uint32)(data[i++] & 0xff);
while (result & mask) {
if (mask == 0x02) {
// seven byte char - invalid
return false;
}
result &= ~mask;
mask >>= 1;
}
while (i < size && (data[i] & 0xc0) == 0x80) {
result <<= 6;
result += data[i++] & 0x3f;
mask <<= 1;
if (mask == 0x40)
break;
}
if (mask != 0x40) {
// not enough bytes in multibyte char
return false;
}
}
return true;
@@ -273,7 +307,7 @@ DataView::Copy()
clip->AddData(B_FILE_MIME_TYPE, B_MIME_TYPE, data, length);
if (is_valid_ascii(data, length))
if (is_valid_utf8(data, length))
clip->AddData("text/plain", B_MIME_TYPE, data, length);
be_clipboard->Commit();
@@ -940,7 +974,7 @@ DataView::InitiateDrag(view_focus focus)
size_t length = fEnd + 1 - fStart;
drag->AddData(B_FILE_MIME_TYPE, B_MIME_TYPE, data, length);
if (is_valid_ascii(data, length))
if (is_valid_utf8(data, length))
drag->AddData("text/plain", B_MIME_TYPE, data, length);
// get a frame that contains the whole selection - SelectionFrame()
+19 -10
View File
@@ -1,14 +1,14 @@
/*
* Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
* Copyright 2004-2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef DATA_VIEW_H
#define DATA_VIEW_H
#include <View.h>
#include <String.h>
#include <Path.h>
#include <String.h>
#include <View.h>
class DataEditor;
@@ -35,7 +35,8 @@ class DataView : public BView {
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit, const BMessage *message);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* message);
virtual void MouseUp(BPoint where);
virtual void KeyDown(const char* bytes, int32 numBytes);
@@ -43,7 +44,8 @@ class DataView : public BView {
virtual void WindowActivated(bool active);
virtual void MakeFocus(bool focus);
virtual void FrameResized(float width, float height);
virtual void SetFont(const BFont *font, uint32 properties = B_FONT_ALL);
virtual void SetFont(const BFont* font,
uint32 properties = B_FONT_ALL);
virtual void GetPreferredSize(float* _width, float* _height);
bool FontSizeFitsBounds() const { return fFitFontSize; }
@@ -53,7 +55,8 @@ class DataView : public BView {
void UpdateScroller();
void MakeVisible(int32 position);
void SetSelection(int32 start, int32 end, view_focus focus = kNoFocus);
void SetSelection(int32 start, int32 end,
view_focus focus = kNoFocus);
void GetSelection(int32& start, int32& end);
void InvalidateRange(int32 start, int32 end);
@@ -64,18 +67,22 @@ class DataView : public BView {
private:
BRect DataBounds(bool inView = false) const;
BRect SelectionFrame(view_focus which, int32 start, int32 end);
int32 PositionAt(view_focus focus, BPoint point, view_focus *_newFocus = NULL);
BRect SelectionFrame(view_focus which, int32 start,
int32 end);
int32 PositionAt(view_focus focus, BPoint point,
view_focus* _newFocus = NULL);
void DrawSelectionFrame(view_focus which);
void DrawSelectionBlock(view_focus which, int32 start, int32 end);
void DrawSelectionBlock(view_focus which, int32 start,
int32 end);
void DrawSelectionBlock(view_focus which);
void DrawSelection(bool frameOnly = false);
void SetActive(bool active);
void SetFocus(view_focus which);
void UpdateFromEditor(BMessage* message = NULL);
void ConvertLine(char *line, off_t offset, const uint8 *buffer, size_t size);
void ConvertLine(char* line, off_t offset,
const uint8* buffer, size_t size);
bool AcceptsDrop(const BMessage* message);
void InitiateDrag(view_focus focus);
@@ -113,4 +120,6 @@ static const uint32 kDataViewCursorPosition = 'curs';
static const uint32 kDataViewSelection = 'dsel';
static const uint32 kDataViewPreferredSize = 'dvps';
extern bool is_valid_utf8(uint8* data, size_t size);
#endif /* DATA_VIEW_H */