<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def index_article(self, msg_str, article_number, start, length):
 """Add article to index file. :type msg_str: str :param msg_str: the message string to index. :type article_number: str :param article_number: the article number to index. :type start: int :param start: the byte-offset where a given message starts in the corresponding mbox file. :type length: int :param length: the byte-length of the message. :rtype: bool :returns: True """

        f = cStringIO.StringIO(msg_str)
        message = rfc822.Message(f)
        f.close()

        # Replace header dict None values with '', and any tabs or
        # newlines with ' '.
        h = dict()
        for key in message.dict:
            if not message.dict[key]:
                h[key] = ''
            h[key] = message.dict[key]
            h[key] = utf8_encode_str(message.dict[key])
            if '\n' in h[key]:
                h[key] = h[key].replace('\n', ' ')
            if '\t' in h[key]:
                h[key] = h[key].replace('\t', ' ')

        date = h.get('NNTP-Posting-Date')
        if not date:
            date = h.get('date', '')
        date = get_utc_iso_date(date)

        idx_line = (date, h.get('message-id'), h.get('from'), h.get('newsgroups'),
                    h.get('subject'), h.get('references', ''), start, length)
        idx_fname = '{name}.{date}.mbox.csv'.format(**self.__dict__)

        s = cStringIO.StringIO()
        writer = csv.writer(s, dialect='excel-tab')
        writer.writerow(idx_line)
        with self._idx_lock:
            with open(idx_fname, 'a') as fp:
                fp.write(s.getvalue())
        s.close()

        return True