Electron open file explorer with file selected43 sec read

After creating a file and writing it to the disk, its nice to show the user the location of the newly created file in the system file explorer.

At the time of writing this there is no option in electron for opening the system file explorer with a file selected. So, like every programmer does I put the title of this post into the google search bar and found this

https://discuss.atom.io/t/opening-the-oss-file-explorer/24348

So this is what I did

function open_file_exp(fpath) {
  var command = '';
  switch (process.platform) {
    case 'darwin':
      command = 'open -R ' + fpath;
      break;
    case 'win32':
      if (process.env.SystemRoot) {
        command = path.join(process.env.SystemRoot, 'explorer.exe');
      } else {
        command = 'explorer.exe';
      }
      command += ' /select,' + fpath;
      break;
    default:
      fpath = path.dirname(fpath)
      command = 'xdg-open ' + fpath;
  }
  console.log(command);
  child_process.exec(command, function(stdout) {
    //Do something if you really need to
  });
}

 

C CRITICAL_SECTION in windows2 min read

CRITICAL_SECTION (MSDN) in Windows can be used for thread synchronization. Essentially you can create a variable and limit it’s ownership to one thread at a time.  Something like this

CRITICAL_SECTION cs;

volatile long counter = 0;

int main(){
  InitializeCriticalSection(&cs);

  //Create threads and run thread_func
  //.....
  //.....
}

void thread_func (){
  //Get ownership of counter
  EnterCriticalSection(&cs);

  //Increment counter
  counter++;

  printf("No. of threads run: %d\n", counter);

  //Leave ownership of counter
  //so that other threads can have it
  LeaveCriticalSection(&cs);
}

Threads block while waiting for ownership of counter . So only one thread will have access to counter  at a time.

Earlier we have created a TCP server using winsock (https://jijnasu.in/c-tcp-server-in-windows-thread-per-connection/). Let’s make use of CRITICAL_SECTION to count the number of requests served by our server.

#include <winsock.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>

#define PORT 50001

//Function that threads run
static DWORD __stdcall func(int s);

//Function to set no. of req served
static void __stdcall inc();

//CRITICAL_SECTION variable
CRITICAL_SECTION cs;

/*
(long counter) to count the
number of requests served.
Volatile so that the
value is read from memory
and not cache
(I think so)
*/
volatile long counter = 0;

int main() {
    //Dont ask just put it in there
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
        fprintf(stderr, "WSAStartup failed.\n");
        exit(1);
    }

    //Socket initiation
    int sock;
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
        printf("Socket initiation failed!");
        return 0;
    }

    //Socket settings
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    memset(addr.sin_zero, '\0', sizeof addr.sin_zero);

    //Bind the socket
    int b;
    if ((b = bind(sock, &addr, sizeof(addr))) == SOCKET_ERROR) {
        printf("Socket initiation failed!");
        return 0;
    }

    //Listen on socket
    int l = listen(sock, 25);

    //Initialize CRITICAL_SECTION
    InitializeCriticalSection(&cs);

    printf("TCP server listening on port %d\n", PORT);

    //If (con) pass it to a new thread
    while (1) {
        struct sockaddr_in client_addr;
        unsigned int c_len = sizeof client_addr;
        int s1 = accept(sock, &client_addr, &c_len);
        unsigned int cur_tid;

        _beginthreadex(NULL, 0, func, s1, 0, &cur_tid);
    }

    //Cleanup
    closesocket(sock);
    WSACleanup();
    return 0;
}

static DWORD __stdcall func(int s) {
    puts("Connection accepted");

    //Read data from client
    char buff[1024];
    unsigned int tot_bytes = recv(s, buff, sizeof(buff), MSG_PEEK);
    char * client_data = (char *)malloc(tot_bytes + 1);
    for (int i = 0; i < (tot_bytes); i++) {
        client_data[i] = buff[i];
    }
    client_data[tot_bytes] = '\0';

    printf("Msg from client: %s\n", client_data);

    //Pretend you are processing info
    puts("Processing req");
    Sleep(5000);
    puts("Processing complete");

    //Prepare message for the client
    char * message;
    if (strcmp(client_data, "COMMAND1") == 0) {
        char lmsg[] = "COMMAND1 recieved";
        message = (char *)malloc(strlen(lmsg));
        message = lmsg;
    }
    else if (strcmp(client_data, "COMMAND2") == 0) {
        char lmsg[] = "COMMAND2 recieved";
        message = (char *)malloc(strlen(lmsg));
        message = lmsg;
    }
    else {
        char lmsg[] = "NO COMMAND recieved";
        message = (char *)malloc(strlen(lmsg));
        message = lmsg;
    }

    free(client_data);

    //Send data to client
    send(s, message, strlen(message), 0);

    inc();

    return 0;
}

static void __stdcall inc() {
    EnterCriticalSection(&cs);
    counter++;
    printf("No. of reqs served: %d\n", counter);
    LeaveCriticalSection(&cs);
}

 

GST check digit validation algorithm2 min read

GST number validation is done through 2 steps

  1. Check if there is a character in position of a character and a number in position of a number.
  2. Validate the check digit that is the last character in the GST no. with  Luhn mod N algorithm (https://en.wikipedia.org/wiki/Luhn_mod_N_algorithm)

An implementation in javascript

let GST = {
  /*
      Luhn mod N algorithm    
      https://en.wikipedia.org/wiki/Luhn_mod_N_algorithm
  */
  chars: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  pattern: /[0-9]{2}[a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[1-9A-Za-z]{1}[Zz1-9A-Ja-j]{1}[0-9a-zA-Z]{1}/,

  generate_check_charcter: function(input) {
    factor = 2;
    sum = 0;
    n = this.number_of_valid_input_chars();

    for (i = input.length - 1; i >= 0; i--) {
      code_point = this.code_point_from_char(input[i]);
      addend = factor * code_point;

      factor = (factor == 2) ? 1 : 2;

      addend = (addend / n) + (addend % n);
      sum += Math.floor(addend);
    }

    remainder = sum % n;
    check_code_point = (n - remainder) % n;

    return this.char_from_code_point(check_code_point);
  },

  validate_check_character: function(input) {
    factor = 1;
    sum = 0;
    n = this.number_of_valid_input_chars();

    for (i = input.length - 1; i >= 0; i--) {
      code_point = this.code_point_from_char(input[i]);
      addend = factor * code_point;

      factor = (factor == 2) ? 1 : 2;

      addend = parseInt(addend / n) + (addend % n);
      sum += addend;
    }

    remainder = sum % n;

    return (remainder == 0);
  },

  number_of_valid_input_chars: function() {
    return this.chars.length;
  },

  code_point_from_char: function(input) {
    let str = this.chars;
    for (let i = 0, q = str.length; i < q; i++) {
      if (input == str[i]) {
        return i;
      }
    }
  },

  char_from_code_point: function(input) {
    let str = this.chars;
    for (let i = 0, q = str.length; i < q; i++) {
      if (input == i) {
        return str[i];
      }
    }
  },

  /*
      Function called to check if a GSTno is valid.
      Full GST.no is passed to the func
  */
  is_valid_num: function(gst_no) {
    //Check for pattern
    var patt = new RegExp(this.pattern);
    if (!patt.test(gst_no)) {
      console.log('pattern wrong');
      return false;
    }

    //Validate the check digit
    return this.validate_check_character(gst_no);
  }

};

USAGE:

GST.is_valid_num(gst_no);

true  is returned if the GST.no is valid. false  if not.

Comment below if you have any questions.