[haiku-commits] haiku: hrev44668 - in src: tests/kits/mail add-ons/kernel/drivers/audio/hda

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 1 Oct 2012 11:12:21 +0200 (CEST)

hrev44668 adds 2 changesets to branch 'master'
old head: 7ba2bcac6f3d71246a2f8506c369babfd101ba3a
new head: a8b45a34711cd202f085a2acb22b151cb2019271

----------------------------------------------------------------------------

225c8cc: Minor cleanup, no functional change.

a8b45a3: Added a test to compare various header parsers.
  
  * HaikuMailFormatFilter is using the new extract_from_header() method
    to retrieve its fields, but that one is often rather slow in comparison.
  * Added a test parse_fields() method that outperforms it considerably.

                                   [ Axel DÃrfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

4 files changed, 253 insertions(+), 35 deletions(-)
.../kernel/drivers/audio/hda/hda_controller.cpp    |   66 +++--
src/tests/kits/Jamfile                             |    1 +
src/tests/kits/mail/Jamfile                        |   11 +
src/tests/kits/mail/header_test.cpp                |  210 ++++++++++++++++

############################################################################

Commit:      225c8cc59aac7901a84ca8baf9957037b31e62fb
URL:         http://cgit.haiku-os.org/haiku/commit/?id=225c8cc
Author:      Axel DÃrfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Mon Oct  1 07:11:35 2012 UTC

Minor cleanup, no functional change.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp 
b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp
index 870a020..c101540 100644
--- a/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp
+++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp
@@ -31,7 +31,7 @@
        (((controller)->num_input_streams + (controller)->num_output_streams \
                + (index)) * HDAC_STREAM_SIZE)
 
-#define ALIGN(size, align)             (((size) + align - 1) & ~(align - 1))
+#define ALIGN(size, align)     (((size) + align - 1) & ~(align - 1))
 #define PAGE_ALIGN(size)       (((size) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 
1))
 
 static const struct {
@@ -58,32 +58,33 @@ static pci_x86_module_info* sPCIx86Module;
 
 
 static inline void
-update_pci_register(hda_controller* controller, uint8 reg, uint32 mask, uint32 
value, uint8 size)
+update_pci_register(hda_controller* controller, uint8 reg, uint32 mask,
+       uint32 value, uint8 size)
 {
-       uint32 tmp = (gPci->read_pci_config)(controller->pci_info.bus,
+       uint32 originalValue = (gPci->read_pci_config)(controller->pci_info.bus,
                controller->pci_info.device, controller->pci_info.function, 
reg, size);
        (gPci->write_pci_config)(controller->pci_info.bus,
                controller->pci_info.device, controller->pci_info.function,
-               reg, size, (tmp & mask) | value);
+               reg, size, (originalValue & mask) | value);
 }
 
 
 static inline rirb_t&
-current_rirb(hda_controller *controller)
+current_rirb(hda_controller* controller)
 {
        return controller->rirb[controller->rirb_read_pos];
 }
 
 
 static inline uint32
-next_rirb(hda_controller *controller)
+next_rirb(hda_controller* controller)
 {
        return (controller->rirb_read_pos + 1) % controller->rirb_length;
 }
 
 
 static inline uint32
-next_corb(hda_controller *controller)
+next_corb(hda_controller* controller)
 {
        return (controller->corb_write_pos + 1) % controller->corb_length;
 }
@@ -105,9 +106,9 @@ stream_handle_interrupt(hda_controller* controller, 
hda_stream* stream,
 
        stream->Write8(HDAC_STREAM_STATUS, status);
 
-       if (status & STATUS_FIFO_ERROR)
+       if ((status & STATUS_FIFO_ERROR) != 0)
                dprintf("hda: stream fifo error (id:%ld)\n", stream->id);
-       if (status & STATUS_DESCRIPTOR_ERROR)
+       if ((status & STATUS_DESCRIPTOR_ERROR) != 0)
                dprintf("hda: stream descriptor error (id:%ld)\n", stream->id);
 
        if ((status & STATUS_BUFFER_COMPLETED) == 0) {
@@ -343,7 +344,8 @@ reset_controller(hda_controller* controller)
 
        // Enable unsolicited responses
        control = controller->Read32(HDAC_GLOBAL_CONTROL);
-       controller->Write32(HDAC_GLOBAL_CONTROL, control | 
GLOBAL_CONTROL_UNSOLICITED);
+       controller->Write32(HDAC_GLOBAL_CONTROL,
+               control | GLOBAL_CONTROL_UNSOLICITED);
 
        return B_OK;
 }
@@ -359,13 +361,8 @@ reset_controller(hda_controller* controller)
 static status_t
 init_corb_rirb_pos(hda_controller* controller)
 {
-       uint32 memSize, rirbOffset, posOffset;
-       uint8 corbSize, rirbSize, posSize;
-       status_t rc = B_OK;
-       physical_entry pe;
-
        // Determine and set size of CORB
-       corbSize = controller->Read8(HDAC_CORB_SIZE);
+       uint8 corbSize = controller->Read8(HDAC_CORB_SIZE);
        if ((corbSize & CORB_SIZE_CAP_256_ENTRIES) != 0) {
                controller->corb_length = 256;
                controller->Write8(HDAC_CORB_SIZE, CORB_SIZE_256_ENTRIES);
@@ -378,7 +375,7 @@ init_corb_rirb_pos(hda_controller* controller)
        }
 
        // Determine and set size of RIRB
-       rirbSize = controller->Read8(HDAC_RIRB_SIZE);
+       uint8 rirbSize = controller->Read8(HDAC_RIRB_SIZE);
        if (rirbSize & RIRB_SIZE_CAP_256_ENTRIES) {
                controller->rirb_length = 256;
                controller->Write8(HDAC_RIRB_SIZE, RIRB_SIZE_256_ENTRIES);
@@ -391,12 +388,13 @@ init_corb_rirb_pos(hda_controller* controller)
        }
 
        // Determine rirb offset in memory and total size of corb+alignment+rirb
-       rirbOffset = ALIGN(controller->corb_length * sizeof(corb_t), 128);
-       posOffset = ALIGN(rirbOffset + controller->rirb_length * 
sizeof(rirb_t), 128);
-       posSize = 8 * (controller->num_input_streams
+       uint32 rirbOffset = ALIGN(controller->corb_length * sizeof(corb_t), 
128);
+       uint32 posOffset = ALIGN(rirbOffset
+               + controller->rirb_length * sizeof(rirb_t), 128);
+       uint8 posSize = 8 * (controller->num_input_streams
                + controller->num_output_streams + 
controller->num_bidir_streams);
 
-       memSize = PAGE_ALIGN(posOffset + posSize);
+       uint32 memSize = PAGE_ALIGN(posOffset + posSize);
 
        // Allocate memory area
        controller->corb_rirb_pos_area = create_area("hda corb/rirb/pos",
@@ -408,9 +406,11 @@ init_corb_rirb_pos(hda_controller* controller)
        // Rirb is after corb+aligment
        controller->rirb = (rirb_t*)(((uint8*)controller->corb) + rirbOffset);
 
-       if ((rc = get_memory_map(controller->corb, memSize, &pe, 1)) != B_OK) {
+       physical_entry pe;
+       status_t status = get_memory_map(controller->corb, memSize, &pe, 1);
+       if (status != B_OK) {
                delete_area(controller->corb_rirb_pos_area);
-               return rc;
+               return status;
        }
 
        // Program CORB/RIRB for these locations
@@ -463,10 +463,10 @@ init_corb_rirb_pos(hda_controller* controller)
 void
 hda_stream_delete(hda_stream* stream)
 {
-       if (stream->buffer_area >= B_OK)
+       if (stream->buffer_area >= 0)
                delete_area(stream->buffer_area);
 
-       if (stream->buffer_descriptors_area >= B_OK)
+       if (stream->buffer_descriptors_area >= 0)
                delete_area(stream->buffer_descriptors_area);
 
        free(stream);
@@ -575,12 +575,12 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, 
hda_stream* stream,
        const char* desc)
 {
        // Clear previously allocated memory
-       if (stream->buffer_area >= B_OK) {
+       if (stream->buffer_area >= 0) {
                delete_area(stream->buffer_area);
                stream->buffer_area = B_ERROR;
        }
 
-       if (stream->buffer_descriptors_area >= B_OK) {
+       if (stream->buffer_descriptors_area >= 0) {
                delete_area(stream->buffer_descriptors_area);
                stream->buffer_descriptors_area = B_ERROR;
        }
@@ -741,7 +741,7 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, 
hda_stream* stream,
 status_t
 hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, uint32 
count)
 {
-       hda_controller *controller = codec->controller;
+       hda_controller* controller = codec->controller;
        uint32 sent = 0;
 
        codec->response_count = 0;
@@ -787,7 +787,7 @@ hda_verb_write(hda_codec* codec, uint32 nid, uint32 vid, 
uint16 payload)
 
 
 status_t
-hda_verb_read(hda_codec* codec, uint32 nid, uint32 vid, uint32 *response)
+hda_verb_read(hda_codec* codec, uint32 nid, uint32 vid, uint32* response)
 {
        corb_t verb = MAKE_VERB(codec->addr, nid, vid, 0);
        return hda_send_verbs(codec, &verb, response, 1);
@@ -987,10 +987,8 @@ error:
 void
 hda_hw_stop(hda_controller* controller)
 {
-       int index;
-
        // Stop all audio streams
-       for (index = 0; index < HDA_MAX_STREAMS; index++) {
+       for (uint32 index = 0; index < HDA_MAX_STREAMS; index++) {
                if (controller->streams[index] && 
controller->streams[index]->running)
                        hda_stream_stop(controller, controller->streams[index]);
        }
@@ -1001,8 +999,6 @@ hda_hw_stop(hda_controller* controller)
 void
 hda_hw_uninit(hda_controller* controller)
 {
-       uint32 index;
-
        if (controller == NULL)
                return;
 
@@ -1050,7 +1046,7 @@ hda_hw_uninit(hda_controller* controller)
        }
 
        // Now delete all codecs
-       for (index = 0; index < HDA_MAX_CODECS; index++) {
+       for (uint32 index = 0; index < HDA_MAX_CODECS; index++) {
                if (controller->codecs[index] != NULL)
                        hda_codec_delete(controller->codecs[index]);
        }

############################################################################

Revision:    hrev44668
Commit:      a8b45a34711cd202f085a2acb22b151cb2019271
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a8b45a3
Author:      Axel DÃrfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Mon Oct  1 08:20:44 2012 UTC

Added a test to compare various header parsers.

* HaikuMailFormatFilter is using the new extract_from_header() method
  to retrieve its fields, but that one is often rather slow in comparison.
* Added a test parse_fields() method that outperforms it considerably.

----------------------------------------------------------------------------

diff --git a/src/tests/kits/Jamfile b/src/tests/kits/Jamfile
index 16ea224..d1739a8 100644
--- a/src/tests/kits/Jamfile
+++ b/src/tests/kits/Jamfile
@@ -5,6 +5,7 @@ SubInclude HAIKU_TOP src tests kits device ;
 SubInclude HAIKU_TOP src tests kits game ;
 SubInclude HAIKU_TOP src tests kits interface ;
 SubInclude HAIKU_TOP src tests kits locale ;
+SubInclude HAIKU_TOP src tests kits mail ;
 SubInclude HAIKU_TOP src tests kits media ;
 SubInclude HAIKU_TOP src tests kits midi ;
 SubInclude HAIKU_TOP src tests kits net ;
diff --git a/src/tests/kits/mail/Jamfile b/src/tests/kits/mail/Jamfile
new file mode 100644
index 0000000..180cf89
--- /dev/null
+++ b/src/tests/kits/mail/Jamfile
@@ -0,0 +1,11 @@
+SubDir HAIKU_TOP src tests kits mail ;
+
+SetSubDirSupportedPlatformsBeOSCompatible ;
+
+UsePrivateHeaders mail shared ;
+
+SimpleTest header_test :
+       header_test.cpp
+
+       : be $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) mail
+;
diff --git a/src/tests/kits/mail/header_test.cpp 
b/src/tests/kits/mail/header_test.cpp
new file mode 100644
index 0000000..5125cd2
--- /dev/null
+++ b/src/tests/kits/mail/header_test.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2012, Axel DÃrfler, axeld@xxxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <BufferIO.h>
+#include <Directory.h>
+#include <Entry.h>
+#include <File.h>
+#include <String.h>
+
+#include <mail_util.h>
+
+
+struct mail_header_field {
+       const char*     rfc_name;
+       const char*     attr_name;
+       type_code       attr_type;
+       // currently either B_STRING_TYPE and B_TIME_TYPE
+};
+
+
+static const mail_header_field gDefaultFields[] = {
+       { "To",                         B_MAIL_ATTR_TO,                 
B_STRING_TYPE },
+       { "From",               B_MAIL_ATTR_FROM,               B_STRING_TYPE },
+       { "Cc",                         B_MAIL_ATTR_CC,                 
B_STRING_TYPE },
+       { "Date",               B_MAIL_ATTR_WHEN,               B_TIME_TYPE   },
+       { "Delivery-Date",      B_MAIL_ATTR_WHEN,               B_TIME_TYPE   },
+       { "Reply-To",           B_MAIL_ATTR_REPLY,              B_STRING_TYPE },
+       { "Subject",            B_MAIL_ATTR_SUBJECT,    B_STRING_TYPE },
+       { "X-Priority",         B_MAIL_ATTR_PRIORITY,   B_STRING_TYPE },
+               // Priorities with prefered
+       { "Priority",           B_MAIL_ATTR_PRIORITY,   B_STRING_TYPE },
+               // one first - the numeric
+       { "X-Msmail-Priority", B_MAIL_ATTR_PRIORITY, B_STRING_TYPE },
+               // one (has more levels).
+       { "Mime-Version",       B_MAIL_ATTR_MIME,               B_STRING_TYPE },
+       { "STATUS",             B_MAIL_ATTR_STATUS,             B_STRING_TYPE },
+       { "THREAD",             B_MAIL_ATTR_THREAD,             B_STRING_TYPE },
+       { "NAME",               B_MAIL_ATTR_NAME,               B_STRING_TYPE },
+       { NULL,                         NULL,                                   
0 }
+};
+
+
+enum mode {
+       PARSE_HEADER,
+       EXTRACT_FROM_HEADER,
+       PARSE_FIELDS
+};
+static mode gParseMode = PARSE_HEADER;
+
+
+void
+format_filter(BFile& file)
+{
+       BMessage message;
+
+       BString header;
+       off_t size;
+       if (file.GetSize(&size) == B_OK) {
+               if (size > 8192)
+                       size = 8192;
+               char* buffer = header.LockBuffer(size);
+               file.Read(buffer, size);
+               header.UnlockBuffer(size);
+       }
+
+       for (int i = 0; gDefaultFields[i].rfc_name; ++i) {
+               BString target;
+               if (extract_from_header(header, gDefaultFields[i].rfc_name, 
target)
+                               == B_OK)
+                       message.AddString(gDefaultFields[i].rfc_name, target);
+       }
+}
+
+
+status_t
+parse_fields(BPositionIO& input, size_t maxSize)
+{
+       char* buffer = (char*)malloc(maxSize);
+       if (buffer == NULL)
+               return B_NO_MEMORY;
+
+       BMessage header;
+
+       ssize_t bytesRead = input.Read(buffer, maxSize);
+       for (int pos = 0; pos < bytesRead; pos++) {
+               const char* target = NULL;
+               int fieldIndex = 0;
+               int fieldStart = 0;
+
+               // Test for fields we should retrieve
+               for (int i = 0; gDefaultFields[i].rfc_name; i++) {
+                       size_t fieldLength = strlen(gDefaultFields[i].rfc_name);
+                       if (!memcmp(&buffer[pos], gDefaultFields[i].rfc_name,
+                                       fieldLength) && buffer[pos + 
fieldLength] == ':') {
+                               target = gDefaultFields[i].rfc_name;
+                               pos += fieldLength + 1;
+                               fieldStart = pos;
+                               fieldIndex = i;
+                               break;
+                       }
+               }
+
+               // Find end of line
+               while (pos < bytesRead && buffer[pos] != '\n')
+                       pos++;
+
+               // Fill in field
+               if (target != NULL) {
+                       // Skip white space
+                       while (isspace(buffer[fieldStart]) && fieldStart < pos)
+                               fieldStart++;
+
+                       int end = pos - 1;
+                       while (isspace(buffer[end]) && fieldStart < end - 1)
+                               end--;
+
+                       char* start = &buffer[fieldStart];
+                       size_t sourceLength = end + 1 - fieldStart;
+                       size_t length = rfc2047_to_utf8(&start, &sourceLength,
+                               sourceLength);
+                       start[length] = '\0';
+
+                       header.AddString(gDefaultFields[fieldIndex].rfc_name, 
start);
+                       target = NULL;
+               }
+       }
+
+       free(buffer);
+       return B_OK;
+}
+
+
+void
+process_file(const BEntry& entry)
+{
+       BFile file(&entry, B_READ_ONLY);
+       if (file.InitCheck() != B_OK) {
+               fprintf(stderr, "could not open file: %s\n",
+                       strerror(file.InitCheck()));
+               return;
+       }
+
+       switch (gParseMode) {
+               case PARSE_HEADER:
+               {
+                       BBufferIO bufferIO(&file, 8192, false);
+                       BMessage headers;
+                       parse_header(headers, bufferIO);
+                       break;
+               }
+               case EXTRACT_FROM_HEADER:
+                       format_filter(file);
+                       break;
+               case PARSE_FIELDS:
+                       parse_fields(file, 8192);
+                       break;
+       }
+}
+
+
+void
+process_directory(const BEntry& directoryEntry)
+{
+       BDirectory directory(&directoryEntry);
+       BEntry entry;
+       while (directory.GetNextEntry(&entry, false) == B_OK) {
+               if (entry.IsDirectory())
+                       process_directory(entry);
+               else
+                       process_file(entry);
+       }
+}
+
+
+int
+main(int argc, char** argv)
+{
+       if (argc < 3) {
+               fprintf(stderr, "Expected: <parse|extract|fields> 
<path-to-mails>\n");
+               return 1;
+       }
+
+       if (!strcmp(argv[1], "parse"))
+               gParseMode = PARSE_HEADER;
+       else if (!strcmp(argv[1], "extract"))
+               gParseMode = EXTRACT_FROM_HEADER;
+       else if (!strcmp(argv[1], "fields"))
+               gParseMode = PARSE_FIELDS;
+       else {
+               fprintf(stderr,
+                       "Invalid type. Must be one of parse, extract, or 
fields.\n");
+               return 1;
+       }
+
+       for (int i = 2; i < argc; i++) {
+               BEntry entry(argv[i]);
+               if (entry.IsDirectory())
+                       process_directory(entry);
+               else
+                       process_file(entry);
+       }
+}


Other related posts:

  • » [haiku-commits] haiku: hrev44668 - in src: tests/kits/mail add-ons/kernel/drivers/audio/hda - axeld