Search code examples
zig

error: expected type '[]u8', found '[]const u8'


I want to create a base64 code as an initial step to create a TLV (Tag-Length-Value) format, I have the below golang code that is working fine:

package main

import (
    "bytes"
    "encoding/base64"
    "fmt"
)

func getTLVForValue(tagNum, tagValue string) []byte {
    tagBuf := []byte(tagNum)
    tagValueLenBuf := []byte{byte(len(tagValue))}
    tagValueBuf := []byte(tagValue)
    bufsArray := [][]byte{tagBuf, tagValueLenBuf, tagValueBuf}
    return bytes.Join(bufsArray, nil)
}

func main() {
    //1. Seller Name
    sellerNameBuf := getTLVForValue("1", "Salah Hospital")

    //2. VAT Registration
    vatRegistrationNameBuf := getTLVForValue("2", "312345678901233")

    tagBufsArray := [][]byte{
        sellerNameBuf,
        vatRegistrationNameBuf,
    }

    qrCodeBuf := bytes.Join(tagBufsArray, nil)

    qrCodeB64 := base64.StdEncoding.EncodeToString(qrCodeBuf)

    fmt.Println(qrCodeB64)
}

And trying to replicate it in zig as:

const std = @import("std");

fn getTLVForValue(allocator: *std.mem.Allocator, tagNum: []const u8, tagValue: []const u8) ![]u8 {
    var tagBuf = try allocator.alloc(u8, tagNum.len);
    std.mem.copy(u8, tagBuf, tagNum);
    var tagValueLenBuf = try allocator.alloc(u8, 1);
    tagValueLenBuf[0] = @intCast(tagValue.len);
    var bufsArray = [_][]u8{tagBuf, tagValueLenBuf, tagValue};
    return std.mem.concat(allocator, u8, bufsArray);
}


pub fn main() !void {
    var allocator = std.heap.page_allocator;

    //1. Seller Name
    const sellerNameBuf = try getTLVForValue(&allocator, "1", "Salah Hospital");

    //2. VAT Registration
    const vatRegistrationNameBuf = try getTLVForValue(&allocator, "2", "312345678901233");

    const tagBufsArray = [_][]u8{
        sellerNameBuf,
        vatRegistrationNameBuf,
    };

    const qrCodeBuf = std.mem.concat(&allocator, u8, tagBufsArray) catch |err| {
        std.debug.print("Error: {}\n", .{err});
        return;
    };

    const qrCodeB64 = std.base64.standard.encode(qrCodeBuf);

    std.debug.print("{}\n", .{qrCodeB64});
}

But it is not working fine, as I got the error:

qr.zig:8:53: error: expected type '[]u8', found '[]const u8'
    var bufsArray = [_][]u8{tagBuf, tagValueLenBuf, tagValue};
                                                    ^~~~~~~~
qr.zig:8:53: note: cast discards const qualifier

how can I fix it, and if there is anything wrong in my approach i do appreciate your guidines.


Solution

  • I solved it with the following code:

    const std = @import("std");
    
    fn getTLVForValue(allocator: std.mem.Allocator, tagNum: []const u8, tagValue: []const u8) ![]u8 {
        var tagBuf = try allocator.alloc(u8, tagNum.len);
        std.mem.copy(u8, tagBuf, tagNum);
        var tagValueLenBuf = try allocator.alloc(u8, 1); 
        tagValueLenBuf[0] = @intCast(tagValue.len);
        var bufsArray = [_][]const u8{tagBuf, tagValueLenBuf, tagValue};
        return std.mem.concat(allocator, u8, &bufsArray);
    }
    
    
    pub fn main() !void {
        var allocator = std.heap.page_allocator;
    
        //1. Seller Name
        const sellerNameBuf = try getTLVForValue(allocator, "01", "Bobs Basement Records");
    
        //2. VAT Registration
        const vatRegistrationNameBuf = try getTLVForValue(allocator, "02", "312345678901233");
    
            //3. Time stamp
        const timeStampBuf = try getTLVForValue(allocator, "03", "12/12/2023");
    
        //4. tax Total
        const taxTotalNameBuf = try getTLVForValue(allocator, "04", "1000");
    
        //5. Vat Total
        const vatTotalBuf = try getTLVForValue(allocator, "05", "115");
    
        //6. Hashed XML
        const hashedXmlBuf = try getTLVForValue(allocator, "06", "dsds");
    
        //7. key
        const keyBuf = try getTLVForValue(allocator, "07", "125");
    
        //8. Signature
        const signatureBuf = try getTLVForValue(allocator, "08", "dsfsd");
    
        const tagBufsArray = [_][]u8{
            sellerNameBuf,
            vatRegistrationNameBuf,
            timeStampBuf,
            taxTotalNameBuf,
            vatTotalBuf,
            hashedXmlBuf,
            keyBuf,
            signatureBuf,
        };
    
        const qrCodeBuf = std.mem.concat(allocator, u8, &tagBufsArray) catch |err| {
            std.debug.print("Error: {}\n", .{err});
            return;
        };
        std.debug.print("{any}\n", .{qrCodeBuf});
        std.debug.print("{}\n", .{ @TypeOf(qrCodeBuf) });
    
        const slice: []const u8 = qrCodeBuf;
        const hexString = try std.fmt.allocPrint(std.heap.page_allocator, "{}", .{std.fmt.fmtSliceHexUpper(slice)});
        defer std.heap.page_allocator.free(hexString);
        std.debug.print("Hex string: {s}\n", .{hexString});
    }