ContentLine.ts 2.11 KB
Newer Older
Mark Stenglein's avatar
Mark Stenglein committed
1 2 3
import { isIamaToken, isAlpha } from "./util";
import Parameter from "./Parameter";
const CRLF: string = "/r/n"
Mark Stenglein's avatar
Mark Stenglein committed
4 5 6 7 8 9 10 11 12 13

/**
 * Implementation of a Content Line from RFC 5545
 *
 * Chapter 3.1 defines the content line. This implementation will use it as an
 * abstract class which can be extended later by the specific content types.
 *
 * This class defines all of the general features specified by the chapter,
 * while leaving the specific features required by individual component objects
 * unfilled.
Mark Stenglein's avatar
Mark Stenglein committed
14 15 16
 *
 * @author Mark Stenglein <mark@stengle.in>
 * @since 0.1.0
Mark Stenglein's avatar
Mark Stenglein committed
17
 */
18
export default class ContentLine {
Mark Stenglein's avatar
Mark Stenglein committed
19
    private _name: string;
Mark Stenglein's avatar
Mark Stenglein committed
20
    private _params: Parameter[] = [];
Mark Stenglein's avatar
Mark Stenglein committed
21 22
    private _value: string;

Mark Stenglein's avatar
Mark Stenglein committed
23
    constructor(inName: string, inParams: Parameter[], inValue: string) {
Mark Stenglein's avatar
Mark Stenglein committed
24
        this.name = inName;
25
        this._params = inParams;
Mark Stenglein's avatar
Mark Stenglein committed
26 27 28 29 30 31 32 33 34
        this.value = inValue;
    }

    /* Getters */

    get name(): string {
        return this._name;
    }

Mark Stenglein's avatar
Mark Stenglein committed
35
    get params(): Parameter[] {
36
        return this._params;
Mark Stenglein's avatar
Mark Stenglein committed
37 38 39 40 41 42 43 44 45
    }

    get value(): string {
        return this._value;
    }

    /* Setters */

    set name(newName: string) {
Mark Stenglein's avatar
Mark Stenglein committed
46
        if (isIamaToken(newName)) {
Mark Stenglein's avatar
Mark Stenglein committed
47 48 49
            this._name = newName;
        }
        else {
50
            throw new TypeError("'name' must be alphabetic!");
Mark Stenglein's avatar
Mark Stenglein committed
51 52 53 54 55 56 57 58
        }
    }

    set value(newValue: string) {
        if (isAlpha(newValue)) {
            this._value = newValue;
        }
    }
59 60 61

    /**
     * Folds lines into 74 octet sections
Mark Stenglein's avatar
Mark Stenglein committed
62
     *
63
     * @author Sebastian Pekarek <mail@sebbo.net>
Mark Stenglein's avatar
Mark Stenglein committed
64
     *
65 66 67
     * TODO: Make sure that this handles multi-octed UTF-8 segments properly.
     */
    static fold(line: string): string {
Mark Stenglein's avatar
Mark Stenglein committed
68
        return line.match(/(.{1,74})/g).join(CRLF + " ");
69 70 71 72
    }

    /**
     * Generates a folded content line to use to create the final file.
Mark Stenglein's avatar
Mark Stenglein committed
73
     *
74 75 76 77 78
     * @author Mark Stenglein <mark@stengle.in>
     */
    public generate(): string {
        let outputLine = this.name;

79
        this.params.forEach((param) => {
80
            outputLine += ";";
81 82 83
            outputLine += param;
        });

Mark Stenglein's avatar
Mark Stenglein committed
84
        outputLine += ":" + this.value + CRLF;
85 86 87

        return ContentLine.fold(outputLine);
    }
88
}